Are You What You Emoji?

How Skin Tone Emojis and Profile Pictures Shape Attention and Social Inference Processing

Author

S.P.

Published

6 November 2024

Information About the R Session

sessionInfo()
R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS 15.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Amsterdam
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] htmlwidgets_1.6.4 compiler_4.3.2    fastmap_1.2.0     cli_3.6.2        
 [5] tools_4.3.2       htmltools_0.5.7   rstudioapi_0.16.0 yaml_2.3.8       
 [9] rmarkdown_2.25    knitr_1.45        jsonlite_1.8.8    xfun_0.41        
[13] digest_0.6.34     rlang_1.1.3       evaluate_0.23    

Set Up

# Set the working directory to the current folder (uncomment)
#setwd(dirname(rstudioapi::getActiveDocumentContext()$path))

# Load packages
list.of.packages <-
  c("qualtRics", # Read files obtained through Qualtrics
    "readr", # Write csv files
    "dplyr", # Manipulate data during preprocessing
    "tidyr", # Manipulate data during preprocessing
    "stringr", # Manipulate strings during preprocessing
    "janitor", # Clean and manage data during preprocessing
    "ggplot2", # Create plots
    "ggfx", # Add drop shadow effect on elements in a plot
    "sur", # Generate descriptive tables
    "vtable", # Generate descriptive tables
    "packHV", # Generate descriptive plots
    "psych", # Conduct reliability tests
    "rstatix", # Identify outliers
    "performance", # Compare models
    "car", # Analyze Variance Inflation Factor (VIF)
    "ordinal", # Execute Cumulative Link Mixed Models (CLMM)
    "RVAideMemoire", # Test CLMM models
    "emmeans", # Perform contrast analysis
    "lme4", # Run Linear Mixed Models
    "kableExtra", # Display tables in HTML format
    "sjPlot", # Generate advanced tables for models
    "report", # Generate advanced reporting for linear models
    "Hmisc", # Generate advanced reporting for cumulative models
    "DHARMa", # Create residuals for models
    "glmmTMB", # Run models with Gamma family
    "gamlss", # Fit relevant parametric distributions
    "effectsize", # Calculate and convert effect sizes
    "nortest", # Run the Anderson-Darling test for normality
    "parameters" # Calculate confidence intervals for contrasts
  )

new.packages <-
  list.of.packages[!(list.of.packages %in% installed.packages()[, "Package"])]
if (length(new.packages))
  install.packages(new.packages) # Install any new packages
lapply(list.of.packages, require, character.only = TRUE) # Library in all packages
rm(list.of.packages, new.packages)

# Remove scientific notation
options(scipen = 999)
options("width"=900)

Data Preprocessing

Eyetracking Data

# Load data
dfet <- read.csv("999_raw_eyetracking_export.csv")

# Changing and translating column names
colnames(dfet) <-
  gsub("\\.", "percent", gsub("_$", "_dup", tolower(colnames(dfet))))

dfet <- dfet %>%
  rename(
    id = recording_session_label,
    profile_pic = perfil_type,
    profile_id = perfil_id,
    receiver_competence = cpr,
    sender_competence = cps,
    emoji_recognition = er,
    academic_field = field,
    conversation_topic = mr,
    quality_relationship = qualrel,
    receiver_black = rbr,
    receiver_white = rwr,
    sender_black = rbs,
    sender_white = rws,
    rt_receiver_competence = rt_cpr,
    rt_sender_competence = rt_cps,
    rt_emoji_recognition = rt_er,
    rt_academic_field = rt_fd,
    rt_key_conversation = rt_key_conversat,
    rt_conversation_topic = rt_mr,
    rt_quality_relationship = rt_qr,
    rt_receiver_black = rt_rbr,
    rt_sender_black = rt_rbs,
    rt_receiver_white = rt_rwr,
    rt_sender_white = rt_rws,
    rt_receiver_warmth = rt_wr,
    rt_sender_warmth = rt_ws,
    receiver_warmth = wr,
    sender_warmth = ws,
    conversation = conversat,
    correct_emoji_recognition = corr_er,
    correct_conversation_topic = corr_mr,
    emoji_location = emoji_locat,
    emoji_hand_type = emoji_type,
    emoji_recognition_option1 = er_item_1,
    emoji_recognition_option2 = er_item_2,
    emoji_recognition_option3 = er_item_3,
    emoji_recognition_option4 = er_item_4,
    emoji_recognition_option5 = er_item_5,
    emoji_recognition_option6 = er_item_6,
    emoji_color = emoji_skin
  )

# Check if there are any duplicated columns
names(dfet)[duplicated(names(dfet))]
character(0)
# Check if the column IDs are exactly the same
identical(dfet$id, dfet$session_name_dup)
[1] TRUE
# Remove column "session_name_dup"
dfet$session_name_dup <- NULL

# Check if there are any recycled trials
table(dfet$trial_recycled_dup)

FALSE 
35040 
# Remove column "trial_recycled_dup"
dfet$trial_recycled_dup <- NULL

# Remove column "trial_index_dup"
dfet$trial_index_dup <- NULL

# Identify columns that contain "_item" in their names
columns_to_remove <- grep("_item", names(dfet), value = TRUE); columns_to_remove
 [1] "cpr_item"     "cps_item"     "fd_item"      "mr_item"      "qualrel_item" "rbr_item"     "rbs_item"     "rwr_item"     "rws_item"     "wr_item"      "ws_item"     
# Remove those columns from the dataframe
dfet <- dfet[, !names(dfet) %in% columns_to_remove]

# Check participants
length(unique(dfet$id)) # 80 participants
[1] 80
# Convert the first four characters of "id" to lowercase
dfet$id <- tolower(substr(dfet$id, 1, 4))

# Transform columns to remove inappropriate commas and dots
columns_with_comma <-
  c("ia_area", "ia_dwell_time_percent", "ia_fixation_percent")
columns_with_dots <-
  c(
    "ia_first_fixation_duration",
    "ia_first_fixation_index",
    "ia_first_run_dwell_time",
    "ia_regression_in",
    "ia_regression_in_count"
  )
dfet <- dfet %>%
  mutate_all( ~ ifelse(. == ".", NA, .)) %>%
  mutate(across(all_of(columns_with_comma), ~ as.numeric(gsub(",", ".", .)))) %>%
  mutate(across(all_of(columns_with_dots), as.numeric))

# Replace problematic characters
character_mapping <- c(
  "√£" = "ã",
  "√ß" = "ç",
  "√©" = "é",
  "√°" = "á",
  "√¢" = "â",
  "√≠" = "í",
  "√≥" = "ó",
  "√™" = "ê",
  "√µ" = "õ",
  "√â" = "é"
)
dfet <- dfet %>% mutate_if(is.character, tolower) %>%
  mutate(across(where(is.character), ~ str_replace_all(., character_mapping)))

# Recode variables
dfet <- dfet %>%
  mutate(profile_pic = case_when(
    profile_pic == "b" ~ "black",
    profile_pic == "w" ~ "white",
    profile_pic == "a" ~ "neutral",
    TRUE ~ profile_pic
  ),
  congruency = case_when(
    congruency == "absent" ~ "neutral",
    TRUE ~ congruency
  ),
  condition = paste0(profile_pic, "pic_", emoji_color, "emoji")
)

# Sanity checks

## Check the number of participants from whom data was collected for their right or left eye
x_eye_used <-
  dfet %>% dplyr::select("id", "eye_used") %>% 
  group_by(id, eye_used) %>%
  summarise(cell_count = n(), .groups = "drop")
table(x_eye_used$eye_used)

 left right 
   10    71 
## Check if all participants viewed both target and filler conversations
x_fillers_count <-
  dfet %>% dplyr::select("id", "filler") %>% 
  group_by(id, filler) %>%
  summarise(cell_count = n(), .groups = "drop")
table(x_fillers_count$filler)

 0  1 
80 80 
## Check if all participants were measured at both areas of interest (emoji and profile picture)
x_ia_count <-
  dfet %>% dplyr::select("id", "ia_label") %>% 
  group_by(id, ia_label) %>%
  summarise(cell_count = n(), .groups = "drop") %>%
  dplyr::filter(ia_label == "aoi_photo" |
                  ia_label == "aoi_emoji")
table(x_ia_count$ia_label)

aoi_emoji aoi_photo 
       80        80 
## Check if all participants saw all conditions
x_trial_count <-
  dfet %>% dplyr::filter(filler == 0) %>%
  dplyr::select("id", "condition") %>% 
  group_by(id, condition) %>%
  summarise(cell_count = n(), .groups = "drop") %>% na.omit()
table(x_trial_count$condition)

    blackpic_darkemoji    blackpic_lightemoji   blackpic_yellowemoji   neutralpic_darkemoji  neutralpic_lightemoji neutralpic_yellowemoji     whitepic_darkemoji    whitepic_lightemoji   whitepic_yellowemoji 
                    80                     80                     80                     80                     80                     80                     80                     80                     80 
rm(list = ls(pattern = "^x_"), 
   columns_with_comma, 
   columns_with_dots, 
   character_mapping, 
   columns_to_remove)

str(dfet)
'data.frame':   35040 obs. of  64 variables:
 $ id                        : chr  "s001" "s001" "s001" "s001" ...
 $ eye_used                  : chr  "right" "right" "right" "right" ...
 $ trial_index               : int  2 2 3 3 4 4 5 5 6 6 ...
 $ ia_label                  : chr  "aoi_photo" "aoi_emoji" "aoi_photo" "aoi_emoji" ...
 $ ia_area                   : num  9764 9764 9764 9764 9764 ...
 $ ip_start_time             : int  2175407 2175407 2272708 2272708 2343156 2343156 2418075 2418075 2479317 2479317 ...
 $ ip_end_time               : int  2184930 2184930 2287835 2287835 2358383 2358383 2429066 2429066 2491342 2491342 ...
 $ ia_dwell_time             : int  0 166 925 1363 2777 1961 1105 0 1443 681 ...
 $ ia_dwell_time_percent     : num  0 0.024 0.0722 0.1063 0.2081 ...
 $ ia_fixation_count         : int  0 1 3 6 9 4 5 0 6 3 ...
 $ ia_fixation_percent       : num  0 0.0345 0.0508 0.1017 0.1765 ...
 $ ia_first_fixation_duration: num  NA 166 365 199 158 930 230 NA 265 261 ...
 $ ia_first_fixation_index   : num  NA 27 10 22 26 24 3 NA 5 34 ...
 $ ia_first_run_dwell_time   : num  NA 166 365 199 674 930 553 NA 583 261 ...
 $ ia_regression_in          : num  NA 0 0 0 1 0 0 NA 1 0 ...
 $ ia_regression_in_count    : num  NA 0 0 0 2 0 0 NA 1 0 ...
 $ ia_run_count              : int  0 1 2 3 6 4 3 0 2 2 ...
 $ receiver_competence       : int  4 4 4 4 4 4 4 4 4 4 ...
 $ sender_competence         : int  5 5 5 5 5 5 5 5 5 5 ...
 $ emoji_recognition         : int  3 3 6 6 3 3 4 4 3 3 ...
 $ academic_field            : int  2 2 1 1 1 1 4 4 2 2 ...
 $ conversation_topic        : int  2 2 1 1 7 7 7 7 1 1 ...
 $ quality_relationship      : int  4 4 6 6 5 5 7 7 6 6 ...
 $ receiver_black            : int  4 4 4 4 4 4 4 4 4 4 ...
 $ sender_black              : int  4 4 3 3 3 3 6 6 2 2 ...
 $ rt_receiver_competence    : int  9220 9220 3970 3970 4144 4144 4243 4243 5554 5554 ...
 $ rt_sender_competence      : int  7036 7036 2470 2470 2519 2519 2536 2536 836 836 ...
 $ rt_emoji_recognition      : int  9931 9931 2168 2168 3403 3403 6695 6695 5643 5643 ...
 $ rt_academic_field         : int  8632 8632 5116 5116 4223 4223 5091 5091 2894 2894 ...
 $ rt_key_conversation       : int  9486 9486 15103 15103 15198 15198 10958 10958 11987 11987 ...
 $ rt_conversation_topic     : int  4329 4329 2331 2331 2184 2184 4272 4272 2560 2560 ...
 $ rt_quality_relationship   : int  13181 13181 2394 2394 3766 3766 1786 1786 2374 2374 ...
 $ rt_receiver_black         : int  1491 1491 7280 7280 1309 1309 756 756 2374 2374 ...
 $ rt_sender_black           : int  1603 1603 5061 5061 7739 7739 2202 2202 5429 5429 ...
 $ rt_receiver_white         : int  5611 5611 7895 7895 5663 5663 3871 3871 2945 2945 ...
 $ rt_sender_white           : int  8340 8340 5122 5122 7888 7888 6703 6703 8432 8432 ...
 $ rt_receiver_warmth        : int  3903 3903 2127 2127 2330 2330 2306 2306 2243 2243 ...
 $ rt_sender_warmth          : int  7056 7056 2126 2126 7226 7226 2765 2765 6276 6276 ...
 $ receiver_white            : int  4 4 4 4 4 4 4 4 4 4 ...
 $ sender_white              : int  4 4 6 6 6 6 2 2 7 7 ...
 $ receiver_warmth           : int  4 4 4 4 4 4 4 4 4 4 ...
 $ sender_warmth             : int  4 4 5 5 5 5 5 5 4 4 ...
 $ congruency                : chr  "neutral" "neutral" "neutral" "neutral" ...
 $ conversation              : int  5 5 9 9 3 3 4 4 8 8 ...
 $ correct_emoji_recognition : int  5 5 6 6 3 3 4 4 4 4 ...
 $ correct_conversation_topic: chr  "não" "não" "sim" "sim" ...
 $ counterbalance            : int  1 1 1 1 1 1 1 1 1 1 ...
 $ emoji_location            : chr  "(647.0, 494.0)" "(647.0, 494.0)" "(647.0, 410.0)" "(647.0, 410.0)" ...
 $ emoji_color               : chr  "yellow" "yellow" "light" "light" ...
 $ emoji_hand_type           : chr  "peace" "peace" "ok" "ok" ...
 $ emoji_recognition_option1 : chr  "tpeace4.png" "tpeace4.png" "tok4.png" "tok4.png" ...
 $ emoji_recognition_option2 : chr  "crossed4.png" "crossed4.png" "crossed0.png" "crossed0.png" ...
 $ emoji_recognition_option3 : chr  "tpeace2.png" "tpeace2.png" "tok0.png" "tok0.png" ...
 $ emoji_recognition_option4 : chr  "crossed2.png" "crossed2.png" "crossed4.png" "crossed4.png" ...
 $ emoji_recognition_option5 : chr  "tpeace0.png" "tpeace0.png" "crossed2.png" "crossed2.png" ...
 $ emoji_recognition_option6 : chr  "crossed0.png" "crossed0.png" "tok2.png" "tok2.png" ...
 $ filler                    : int  0 0 0 0 0 0 0 0 0 0 ...
 $ first_name                : chr  "luísa" "luísa" "vânia" "vânia" ...
 $ full_name                 : chr  "luísa loureiro" "luísa loureiro" "vânia lourenço" "vânia lourenço" ...
 $ list                      : chr  "a" "a" "a" "a" ...
 $ profile_id                : chr  "a2" "a2" "a1" "a1" ...
 $ profile_pic               : chr  "neutral" "neutral" "neutral" "neutral" ...
 $ picture                   : chr  "5a2yellowpeace.png" "5a2yellowpeace.png" "9a1lightok.png" "9a1lightok.png" ...
 $ condition                 : chr  "neutralpic_yellowemoji" "neutralpic_yellowemoji" "neutralpic_lightemoji" "neutralpic_lightemoji" ...

Main Survey Data

The responses in the columns racial_groups_5_TEXT, racial_groups_6_TEXT, white_group, white_group_5_TEXT, black_group, black_group_7_TEXT, asian_group, asian_group_10_TEXT, romani_group, and romani_group_3_TEXT have been removed from the raw data file for privacy reasons. These data are available upon request.

# Load data
dfq <- read_survey("999_raw_qualtrics_main.csv")

# Transform the dataframe
dfq <- dfq %>%
  
  ## Reformat column names
  janitor::clean_names() %>%
  rename(id = participant_code,
         texting_usage = texting_usage_8) %>%
  
  ## Convert text to lowercase
  mutate_if(is.character, tolower) %>%
  
  ## Filter out unfinished trials and 
  ## select rows where 'id' contains 's' and has 4 or fewer characters 
  filter(!(finished == FALSE), grepl("s", id) & nchar(id) <= 4) %>%
  
  mutate(
    ## Correct values from "s041" to "s044". 
    ## The person who administered the task in the lab reported 
    ## their mistake with the participant code.
    id = if_else(response_id == "r_1dxsfwtevfapfir", "s044", id),
    
    ## Correct values for racialized group identification and cross-group friendship 
    ## because the participant s061 mistakenly chose "other" and wrote "White" 
    ## instead of selecting the "White" option.
    racial_groups = if_else(id == "s061", "branco", racial_groups),
    
    ## Recode variables
    cross1_white_nr = case_when(
      cross1_white == "nenhum" ~ 0,
      cross1_white == "um" ~ 1,
      cross1_white == "entre dois a cinco" ~ 2,
      cross1_white == "entre cinco a dez" ~ 3,
      cross1_white == "mais de dez" ~ 4,
      TRUE ~ NA_integer_
    ),
    cross1_white = case_when(
      cross1_white == "nenhum" ~ "none",
      cross1_white == "um" ~ "one",
      cross1_white == "entre dois a cinco" ~ "two to five",
      cross1_white == "entre cinco a dez" ~ "five to ten",
      cross1_white == "mais de dez" ~ "more than ten",
      TRUE ~ NA_character_
    ),
    
    cross2_white_nr = case_when(
      cross2_white == "nunca" ~ 1,
      cross2_white == "ocasionalmente" ~ 2,
      cross2_white == "às vezes" ~ 3,
      cross2_white == "várias vezes" ~ 4,
      cross2_white == "constantemente" ~ 5,
      TRUE ~ 0 ## For participants who responded with "none" to "cross1_white"
    ),
    
    cross2_white = case_when(
      cross2_white == "nunca" ~ "never",
      cross2_white == "ocasionalmente" ~ "occasionally",
      cross2_white == "às vezes" ~ "sometimes",
      cross2_white == "várias vezes" ~ "many times",
      cross2_white == "constantemente" ~ "all the time",
      TRUE ~ NA_character_
    ),
    
    skin_tone_usage = case_when(
      skin_tone_usage == "não" ~ 0,
      skin_tone_usage == "sim" ~ 1,
      TRUE ~ NA_integer_
    ),
    
    ## Compute new variables
    att_mean = (
      att_matrix_1 + att_matrix_2 + att_matrix_3 + 
        att_matrix_4 + att_matrix_5 + att_matrix_6) / 6) %>%
  
  ## Relocate
  relocate(att_mean, .after = att_matrix_6) %>%
  relocate(cross1_white_nr, .after = cross1_white) %>%
  relocate(cross2_white_nr, .after = cross2_white) %>%

  # Remove columns
  dplyr::select(-user_language) %>%
  
  # Add the suffix "_mainsurvey" to repeated columns with sociodemographic survey
  rename_with(~paste0(., "_mainsurvey"), 
              .cols = c("start_date", "end_date", "status", 
                        "progress","duration_in_seconds", "finished",
                        "recorded_date", "response_id", "distribution_channel"
                        ))

# Check participants
length(unique(dfq$id)) # 80 participants
[1] 80
# Check racialized identification
table(dfq$racial_groups) # 76 white; 4 black participants

branco  negro 
    76      4 
ids_remove_participants <- dfq %>%
  filter(racial_groups == "negro") %>%
  dplyr::select(id) # 13, 14, 64, and 70

# Check text messaging values
table(dfq$texting_usage) # nobody reported not using text messaging chats

  6   7   9  10  13  15  20  30  40  51  57  60  63  65  70  71  72  73  75  80  81  85  90  91  92  94  95  97 100 
  1   1   1   1   1   1   2   4   2   1   1   3   1   1   5   6   2   2   2   5   4   4   5   4   1   1   3   1  14 
str(dfq)
tibble [80 × 60] (S3: tbl_df/tbl/data.frame)
 $ start_date_mainsurvey          : POSIXct[1:80], format: "2022-03-09 09:06:50" "2022-03-09 10:26:11" "2022-03-09 11:37:18" "2022-03-09 12:49:54" ...
 $ end_date_mainsurvey            : POSIXct[1:80], format: "2022-03-09 10:11:56" "2022-03-09 11:24:42" "2022-03-09 12:40:04" "2022-03-09 14:29:54" ...
 $ status_mainsurvey              : chr [1:80] "ip address" "ip address" "ip address" "ip address" ...
  ..- attr(*, "label")= Named chr "Response Type"
  .. ..- attr(*, "names")= chr "Status"
 $ progress_mainsurvey            : num [1:80] 100 100 100 100 100 100 100 100 100 100 ...
  ..- attr(*, "label")= Named chr "Progress"
  .. ..- attr(*, "names")= chr "Progress"
 $ duration_in_seconds_mainsurvey : num [1:80] 3905 3511 3765 5999 3655 ...
  ..- attr(*, "label")= Named chr "Duration (in seconds)"
  .. ..- attr(*, "names")= chr "Duration (in seconds)"
 $ finished_mainsurvey            : logi [1:80] TRUE TRUE TRUE TRUE TRUE TRUE ...
  ..- attr(*, "label")= Named chr "Finished"
  .. ..- attr(*, "names")= chr "Finished"
 $ recorded_date_mainsurvey       : POSIXct[1:80], format: "2022-03-09 10:11:57" "2022-03-09 11:24:43" "2022-03-09 12:40:04" "2022-03-09 14:29:54" ...
 $ response_id_mainsurvey         : chr [1:80] "r_3oyzcrk1uvw7y06" "r_xguhkqyjq1ilfup" "r_btxq9mifzv3shuz" "r_sb5mov1ubd8dtq5" ...
  ..- attr(*, "label")= Named chr "Response ID"
  .. ..- attr(*, "names")= chr "ResponseId"
 $ distribution_channel_mainsurvey: chr [1:80] "anonymous" "anonymous" "anonymous" "anonymous" ...
  ..- attr(*, "label")= Named chr "Distribution Channel"
  .. ..- attr(*, "names")= chr "DistributionChannel"
 $ id                             : chr [1:80] "s001" "s002" "s003" "s004" ...
 $ texting_usage                  : num [1:80] 100 100 73 90 71 95 100 63 13 73 ...
  ..- attr(*, "label")= Named chr "Com que frequência usa, num dia típico, serviços de mensagens de texto? (por exemplo, Whatsapp, Messenger, Sign"| __truncated__
  .. ..- attr(*, "names")= chr "texting_usage_8"
 $ emoji_usage1                   : num [1:80] 6 6 6 5 6 6 5 6 4 4 ...
  ..- attr(*, "label")= Named chr "Nas suas comunicações escritas, com que frequência envia emojis?"
  .. ..- attr(*, "names")= chr "emoji_usage1"
 $ emoji_usage2                   : num [1:80] 6 6 6 5 6 6 6 6 5 5 ...
  ..- attr(*, "label")= Named chr "Nas suas comunicações escritas, com que frequência recebe emojis?"
  .. ..- attr(*, "names")= chr "emoji_usage2"
 $ skin_color_id                  : num [1:80] 1 2 2 1 2 1 2 1 2 2 ...
  ..- attr(*, "label")= Named chr "No geral, o meu tom de pele é mais semelhante com..."
  .. ..- attr(*, "names")= chr "skin_color_id"
 $ racial_groups                  : chr [1:80] "branco" "branco" "branco" "branco" ...
 $ racial_groups_5_text           : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Qual das seguintes opções considera que melhor descreve a sua pertença e/ou origem?\n\n(Escolha apenas um) - Ou"| __truncated__
  .. ..- attr(*, "names")= chr "racial_groups_5_TEXT"
 $ racial_groups_6_text           : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Qual das seguintes opções considera que melhor descreve a sua pertença e/ou origem?\n\n(Escolha apenas um) - Or"| __truncated__
  .. ..- attr(*, "names")= chr "racial_groups_6_TEXT"
 $ white_group                    : chr [1:80] "available upon request" "available upon request" "available upon request" "available upon request" ...
  ..- attr(*, "label")= Named chr "Branco / Português branco / De origem europeia - Selected Choice"
  .. ..- attr(*, "names")= chr "white_group"
 $ white_group_5_text             : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Branco / Português branco / De origem europeia - outra origem. Qual? - Texto"
  .. ..- attr(*, "names")= chr "white_group_5_TEXT"
 $ black_group                    : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Negro / Português Negro / Afrodescendente / De origem africana - Selected Choice"
  .. ..- attr(*, "names")= chr "black_group"
 $ black_group_7_text             : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Negro / Português Negro / Afrodescendente / De origem africana - outra origem. Qual? - Texto"
  .. ..- attr(*, "names")= chr "black_group_7_TEXT"
 $ asian_group                    : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Asiático / Português de origem asiática / De origem asiática - Selected Choice"
  .. ..- attr(*, "names")= chr "asian_group"
 $ asian_group_10_text            : logi [1:80] NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Asiático / Português de origem asiática / De origem asiática - outra origem. Qual? - Texto"
  .. ..- attr(*, "names")= chr "asian_group_10_TEXT"
 $ romani_group                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Cigano / Português cigano / Roma / De origem cigana - Selected Choice"
  .. ..- attr(*, "names")= chr "romani_group"
 $ romani_group_3_text            : logi [1:80] NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Cigano / Português cigano / Roma / De origem cigana - outra origem. Qual? - Texto"
  .. ..- attr(*, "names")= chr "romani_group_3_TEXT"
 $ identification_level           : num [1:80] 6 6 5 7 5 7 7 7 6 6 ...
  ..- attr(*, "label")= Named chr "Eu identifico-me com [QID5-ChoiceTextEntryValue-5][QID5-ChoiceTextEntryValue-6][QID6-ChoiceGroup-SelectedChoice"| __truncated__
  .. ..- attr(*, "names")= chr "identification_level"
 $ cross1_white                   : chr [1:80] "more than ten" "none" "two to five" "one" ...
 $ cross1_white_nr                : num [1:80] 4 0 2 1 2 2 3 2 3 2 ...
 $ cross1_black                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Quantos amigos seus são Brancos, Asiáticos, Ciganos ou Bi-raciais?"
  .. ..- attr(*, "names")= chr "cross1_black"
 $ cross1_asian                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Quantos amigos seus são Brancos, Negros, Ciganos ou Bi-raciais?"
  .. ..- attr(*, "names")= chr "cross1_asian"
 $ cross1_romani                  : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Quantos amigos seus são Brancos, Negros, Asiáticos ou Bi-raciais?"
  .. ..- attr(*, "names")= chr "cross1_romani"
 $ cross1_mixed                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Quantos amigos seus são Brancos, Negros, Asiáticos, Ciganos, ou Bi-raciais de diferentes origens?"
  .. ..- attr(*, "names")= chr "cross1_mixed"
 $ cross1_other                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Quantos amigos seus são Brancos, Negros, Asiáticos, Ciganos ou Bi-raciais?"
  .. ..- attr(*, "names")= chr "cross1_other"
 $ cross2_white                   : chr [1:80] "all the time" NA "occasionally" "occasionally" ...
 $ cross2_white_nr                : num [1:80] 5 0 2 2 3 5 5 3 2 3 ...
 $ cross2_other                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Com que frequência passa tempo com amigos que são Brancos, Negros, Asiáticos, Ciganos ou Bi-raciais?"
  .. ..- attr(*, "names")= chr "cross2_other"
 $ cross2_black                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Com que frequência passa tempo com amigos que são Brancos, Asiáticos, Ciganos ou Bi-raciais?"
  .. ..- attr(*, "names")= chr "cross2_black"
 $ cross2_asian                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Com que frequência passa tempo com amigos que são Brancos, Negros, Ciganos ou Bi-raciais?"
  .. ..- attr(*, "names")= chr "cross2_asian"
 $ cross2_romani                  : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Com que frequência passa tempo com amigos que são Brancos, Negros, Asiáticos ou Bi-raciais?"
  .. ..- attr(*, "names")= chr "cross2_romani"
 $ cross2_mixed                   : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Com que frequência passa tempo com amigos que são Brancos, Negros, Asiáticos, Ciganos, ou Bi-raciais de diferentes origens?"
  .. ..- attr(*, "names")= chr "cross2_mixed"
 $ att_matrix_1                   : num [1:80] 6 3 4 4 4 4 4 5 4 4 ...
  ..- attr(*, "label")= Named chr "Para mim, usar emojis com tons de pele nas mensagens seria... - muito mau:muito bom"
  .. ..- attr(*, "names")= chr "att_matrix_1"
 $ att_matrix_2                   : num [1:80] 4 3 4 4 4 4 4 4 4 3 ...
  ..- attr(*, "label")= Named chr "Para mim, usar emojis com tons de pele nas mensagens seria... - muito prejudicial:muito benéfico"
  .. ..- attr(*, "names")= chr "att_matrix_2"
 $ att_matrix_3                   : num [1:80] 5 3 4 4 4 4 4 5 4 3 ...
  ..- attr(*, "label")= Named chr "Para mim, usar emojis com tons de pele nas mensagens seria... - muito insensato:muito sensato"
  .. ..- attr(*, "names")= chr "att_matrix_3"
 $ att_matrix_4                   : num [1:80] 5 3 4 4 1 4 4 5 4 4 ...
  ..- attr(*, "label")= Named chr "Para mim, usar emojis com tons de pele nas mensagens seria... - muito desagradável:muito agradável"
  .. ..- attr(*, "names")= chr "att_matrix_4"
 $ att_matrix_5                   : num [1:80] 4 3 4 4 1 4 4 5 4 4 ...
  ..- attr(*, "label")= Named chr "Para mim, usar emojis com tons de pele nas mensagens seria... - muito desconfortável:muito confortável"
  .. ..- attr(*, "names")= chr "att_matrix_5"
 $ att_matrix_6                   : num [1:80] 5 3 4 4 4 5 4 5 4 4 ...
  ..- attr(*, "label")= Named chr "Para mim, usar emojis com tons de pele nas mensagens seria... - muito aborrecido:muito divertido"
  .. ..- attr(*, "names")= chr "att_matrix_6"
 $ att_mean                       : num [1:80] 4.83 3 4 4 3 ...
  ..- attr(*, "label")= Named chr "Para mim, usar emojis com tons de pele nas mensagens seria... - muito mau:muito bom"
  .. ..- attr(*, "names")= chr "att_matrix_1"
 $ inj_white                      : num [1:80] 6 6 7 7 4 5 4 6 7 7 ...
  ..- attr(*, "label")= Named chr "Se eu usasse emojis com tom de pele claro, a maioria das pessoas que eu conheço iria..."
  .. ..- attr(*, "names")= chr "inj_white"
 $ inj_black                      : num [1:80] 2 4 7 4 7 3 4 3 7 4 ...
  ..- attr(*, "label")= Named chr "Se eu usasse emojis com tom de pele escuro, a maioria das pessoas que eu conheço iria..."
  .. ..- attr(*, "names")= chr "inj_black"
 $ inj_yellow                     : num [1:80] 7 7 7 7 7 4 4 6 7 7 ...
  ..- attr(*, "label")= Named chr "Se eu usasse emojis com tom de pele amarelo, a maioria das pessoas que eu conheço iria..."
  .. ..- attr(*, "names")= chr "inj_yellow"
 $ inj_should_1                   : num [1:80] 6 4 4 4 4 4 4 4 4 4 ...
  ..- attr(*, "label")= Named chr "A maioria das pessoas que eu conheço pensa que eu... - Não devo usaremojis com tons de pele:Devo usaremojis com tons de pele"
  .. ..- attr(*, "names")= chr "inj_should_1"
 $ inj_importance                 : num [1:80] 4 1 4 1 2 4 4 3 2 1 ...
  ..- attr(*, "label")= Named chr "Na sua estimativa, quão importante é usar emoji com tons de pele para um típico jovem?"
  .. ..- attr(*, "names")= chr "inj_importance"
 $ descriptive_norm               : num [1:80] 6 2 4 6 2 6 4 5 4 5 ...
  ..- attr(*, "label")= Named chr "Na sua estimativa, com que frequência um jovem típico usa emoji com tons de pele?"
  .. ..- attr(*, "names")= chr "descriptive_norm"
 $ skin_tone_usage                : num [1:80] 1 1 1 0 1 1 0 1 0 1 ...
 $ skin_tone_emoji_id             : num [1:80] 2 3 2 NA 2 2 NA 1 NA 2 ...
  ..- attr(*, "label")= Named chr "Entre estes tons de pele, qual é que mais utilizou nos emojis?"
  .. ..- attr(*, "names")= chr "skin_tone_emoji_ID"
 $ usage_skintone1                : num [1:80] 3 1 5 NA 2 5 NA 4 NA 2 ...
  ..- attr(*, "label")= Named chr "Nas suas comunicações escritas, com que frequência envia emojis tons de pele?"
  .. ..- attr(*, "names")= chr "usage_skintone1"
 $ usage_skintone2                : num [1:80] 3 2 5 5 2 5 4 4 5 2 ...
  ..- attr(*, "label")= Named chr "Nas suas comunicações escritas, com que frequência recebe emojis tons de pele?"
  .. ..- attr(*, "names")= chr "usage_skintone2"
 $ politic_left_right             : num [1:80] 3 6 5 4 6 5 1 5 1 6 ...
  ..- attr(*, "label")= Named chr "Em termos políticos, as pessoas falam de \"a esquerda\" e \"a direita\".\nComo colocaria a sua opinião nesta es"| __truncated__
  .. ..- attr(*, "names")= chr "politic_left_right"
 $ goal_suspected                 : chr [1:80] "perceber de que maneira o uso de emojis com tom de pele pode alterar a perceção do recetor." "perceber a influência da utilização de emojis com cor de pele, se conta mais a fotografia da pessoa no whatsapp"| __truncated__ "ver se prestamos atenção aos tons de pele utilizados nos emojis e se os associamos às pessoas" "na minha opinião o objetivo era ver se existe alguma relação entre a utilização de emojis com tons de pele e a "| __truncated__ ...
  ..- attr(*, "label")= Named chr "Na sua opinião, qual foi o objetivo deste estudo?"
  .. ..- attr(*, "names")= chr "goal_suspected"
 $ emoji_influence                : num [1:80] 4 5 5 5 5 6 5 3 2 6 ...
  ..- attr(*, "label")= Named chr "Nesta tarefa estamos interessados em compreender como as pessoas interpretam diferentes tipos de emojis.\n\nNa "| __truncated__
  .. ..- attr(*, "names")= chr "emoji_influence"
 - attr(*, "column_map")= tibble [58 × 7] (S3: tbl_df/tbl/data.frame)
  ..$ qname      : chr [1:58] "StartDate" "EndDate" "Status" "Progress" ...
  ..$ description: chr [1:58] "Start Date" "End Date" "Response Type" "Progress" ...
  ..$ main       : chr [1:58] "Start Date" "End Date" "Response Type" "Progress" ...
  ..$ sub        : chr [1:58] "" "" "" "" ...
  ..$ ImportId   : chr [1:58] "startDate" "endDate" "status" "progress" ...
  ..$ timeZone   : chr [1:58] "Europe/London" "Europe/London" NA NA ...
  ..$ choiceId   : logi [1:58] NA NA NA NA NA NA ...
rm(ids_remove_participants)

Sociodemographic Survey Data

# Load data
dfs <- read_survey("999_raw_qualtrics_sociodemographic.csv")

# Transform the dataframe
dfs <- dfs %>% 
  
  # Reformat column names
  janitor::clean_names() %>%
  rename(id = codigo_id) %>%
  
  # Convert text to lowercase
  mutate_if(is.character, tolower) %>%
  
  # Keep the rows where participants have finished the survey and have a correct ID
  filter(!(finished == 0), grepl("s", id)) %>%
  
  # Correct values from "s00399" to "s003"
  mutate(id = if_else(response_id == "r_2cnoxenj00osqy4", "s003", id)) %>%
  
  # Remove columns
  dplyr::select(-user_language) %>%
  
  # Add the suffix "_sociosurvey" to repeated columns with main survey
  rename_with(~paste0(., "_sociosurvey"), 
              .cols = c("start_date", "end_date", "status", 
                        "progress","duration_in_seconds", "finished",
                        "recorded_date", "response_id", "distribution_channel"
                        ))

# Check if participants mistakenly wrote their gender instead of selecting the options
unique(dfs$gender_9_text)
[1] NA
# Check the age values
table(dfs$age)

18 19 20 21 22 23 24 25 26 28 31 35 39 48 49 50 56 62 64 
11 10  9 11 18  6  2  1  1  1  1  1  1  1  1  2  1  1  1 
# Check the gender values
table(dfs$gender)

 0  1  9 
18 61  1 
unique(dfs$gender_9_text)
[1] NA
# Check nationality
table(dfs$nationality) # 78 Portuguese participants; 2 other

 1  2 
78  2 
unique(dfs$nationality_2_text)
[1] NA           "brasileira"
# Check 
table(dfs$language) # 78 Portuguese participants; 2 other

 0  1 
 2 78 
# Check 
table(dfs$fluency_pt)

2 5 
1 1 
ids_lowfluency_participants <- dfs %>%
  filter(fluency_pt < 5) %>%
  dplyr::select(id) # 64

# Check participants
length(unique(dfs$id)) # 80 participants
[1] 80
str(dfs)
tibble [80 × 25] (S3: tbl_df/tbl/data.frame)
 $ start_date_sociosurvey          : POSIXct[1:80], format: "2022-03-09 10:19:43" "2022-03-09 11:30:52" "2022-03-09 12:45:49" "2022-03-09 14:40:02" ...
 $ end_date_sociosurvey            : POSIXct[1:80], format: "2022-03-09 10:20:03" "2022-03-09 11:31:09" "2022-03-09 12:46:14" "2022-03-09 14:40:43" ...
 $ status_sociosurvey              : num [1:80] 0 0 0 0 0 0 0 0 0 0 ...
  ..- attr(*, "label")= Named chr "Response Type"
  .. ..- attr(*, "names")= chr "Status"
 $ progress_sociosurvey            : num [1:80] 100 100 100 100 100 100 100 100 100 100 ...
  ..- attr(*, "label")= Named chr "Progress"
  .. ..- attr(*, "names")= chr "Progress"
 $ duration_in_seconds_sociosurvey : num [1:80] 20 16 25 41 34 19 29 18 20 24 ...
  ..- attr(*, "label")= Named chr "Duration (in seconds)"
  .. ..- attr(*, "names")= chr "Duration..in.seconds."
 $ finished_sociosurvey            : num [1:80] 1 1 1 1 1 1 1 1 1 1 ...
  ..- attr(*, "label")= Named chr "Finished"
  .. ..- attr(*, "names")= chr "Finished"
 $ recorded_date_sociosurvey       : POSIXct[1:80], format: "2022-03-09 10:20:04" "2022-03-09 11:31:10" "2022-03-09 12:46:15" "2022-03-09 14:40:44" ...
 $ response_id_sociosurvey         : chr [1:80] "r_1cciz2fmjnowlvz" "r_3oxw57rpevhbmih" "r_2cnoxenj00osqy4" "r_2cixihtfqwnnts8" ...
  ..- attr(*, "label")= Named chr "Response ID"
  .. ..- attr(*, "names")= chr "ResponseId"
 $ recipient_last_name             : logi [1:80] NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Recipient Last Name"
  .. ..- attr(*, "names")= chr "RecipientLastName"
 $ recipient_first_name            : logi [1:80] NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Recipient First Name"
  .. ..- attr(*, "names")= chr "RecipientFirstName"
 $ recipient_email                 : logi [1:80] NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Recipient Email"
  .. ..- attr(*, "names")= chr "RecipientEmail"
 $ external_reference              : logi [1:80] NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "External Data Reference"
  .. ..- attr(*, "names")= chr "ExternalReference"
 $ distribution_channel_sociosurvey: chr [1:80] "anonymous" "anonymous" "anonymous" "anonymous" ...
  ..- attr(*, "label")= Named chr "Distribution Channel"
  .. ..- attr(*, "names")= chr "DistributionChannel"
 $ age                             : num [1:80] 19 22 21 21 49 19 48 20 50 18 ...
  ..- attr(*, "label")= Named chr "Pode escrever a sua idade (em números), por favor?"
  .. ..- attr(*, "names")= chr "age"
 $ gender                          : num [1:80] 1 1 1 1 1 1 1 1 1 1 ...
  ..- attr(*, "label")= Named chr "Qual é o seu sexo? - Selected Choice"
  .. ..- attr(*, "names")= chr "gender"
 $ gender_9_text                   : logi [1:80] NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Qual é o seu sexo? - Outro. Identifico o meu sexo como: - Texto"
  .. ..- attr(*, "names")= chr "gender_9_TEXT"
 $ nationality                     : num [1:80] 1 1 1 1 1 1 1 1 1 1 ...
  ..- attr(*, "label")= Named chr "Qual é a sua nacionalidade? - Selected Choice"
  .. ..- attr(*, "names")= chr "nationality"
 $ nationality_2_text              : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Qual é a sua nacionalidade? - Outra - Texto"
  .. ..- attr(*, "names")= chr "nationality_2_TEXT"
 $ language                        : num [1:80] 1 1 1 1 1 1 1 1 1 1 ...
  ..- attr(*, "label")= Named chr "Português europeu é a sua língua nativa?"
  .. ..- attr(*, "names")= chr "language"
 $ residence_pt                    : chr [1:80] NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Há quantos anos reside em Portugal?"
  .. ..- attr(*, "names")= chr "residence_pt"
 $ fluency_pt                      : num [1:80] NA NA NA NA NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Como avalia a sua fluência em Português (Europeu)?"
  .. ..- attr(*, "names")= chr "fluency_pt"
 $ education                       : num [1:80] 2 4 2 2 4 2 3 2 5 2 ...
  ..- attr(*, "label")= Named chr "Qual é o nível de educação mais elevado que já concluiu? - Selected Choice"
  .. ..- attr(*, "names")= chr "education"
 $ education_7_text                : logi [1:80] NA NA NA NA NA NA ...
  ..- attr(*, "label")= Named chr "Qual é o nível de educação mais elevado que já concluiu? - Outro - Texto"
  .. ..- attr(*, "names")= chr "education_7_TEXT"
 $ occupation                      : num [1:80] 1 1 2 1 2 1 2 1 2 1 ...
  ..- attr(*, "label")= Named chr "Qual é a sua situação laboral?"
  .. ..- attr(*, "names")= chr "occupation"
 $ id                              : chr [1:80] "s001" "s002" "s003" "s004" ...
 - attr(*, "column_map")= tibble [26 × 7] (S3: tbl_df/tbl/data.frame)
  ..$ qname      : chr [1:26] "StartDate" "EndDate" "Status" "Progress" ...
  ..$ description: chr [1:26] "Start Date" "End Date" "Response Type" "Progress" ...
  ..$ main       : chr [1:26] "Start Date" "End Date" "Response Type" "Progress" ...
  ..$ sub        : chr [1:26] "" "" "" "" ...
  ..$ ImportId   : chr [1:26] "startDate" "endDate" "status" "progress" ...
  ..$ timeZone   : chr [1:26] "Europe/London" "Europe/London" NA NA ...
  ..$ choiceId   : logi [1:26] NA NA NA NA NA NA ...
rm(ids_lowfluency_participants)

Data Wrangling

# Sanity Check
## Check which columns are repeated across dataframes
dplyr::intersect(names(dfq), names(dfs)) # only id
[1] "id"
dplyr::intersect(names(dfq), names(dfet)) # only id
[1] "id"
dplyr::intersect(names(dfs), names(dfet)) # only id
[1] "id"
# Merge dataframes
df <- merge(merge(dfet, dfq, by = "id", all = TRUE), dfs, by = "id", all = TRUE)

# Add information about who volunteered and who received partial credit
# This was not directly recorded in the data to comply with privacy regulations.
credit_ids <-
  tolower(
    c(
      "S001",
      "S002",
      "S003",
      "S004",
      "S005",
      "S006",
      "S007",
      "S008",
      "S009",
      "S010",
      "S011",
      "S012",
      "S013",
      "S014",
      "S015",
      "S016",
      "S017",
      "S018",
      "S019",
      "S020",
      "S021",
      "S022",
      "S023",
      "S024",
      "S025",
      "S026",
      "S027",
      "S028",
      "S029",
      "S030",
      "S078",
      "S079",
      "S080"
    )
  )

df <- df %>%
  mutate(volunteer = ifelse(id %in% credit_ids, "credit", "volunteer"))

# Transform certain variables into ordered factors
df <- df %>%
  mutate(
    sender_competence_f = as.ordered(sender_competence),
    sender_warmth_f = as.ordered(sender_warmth),
    quality_relationship_f = as.ordered(quality_relationship))

# Relocate columns
df <- df %>%
  relocate(congruency, .after = eye_used) %>%
  relocate(emoji_color, .after = congruency) %>%
  relocate(profile_pic, .after = emoji_color) %>%
  relocate(condition, .after = id) %>%
  relocate(filler, .after = condition) %>%
  relocate(age, .after = id) %>%
  relocate(gender, .after = id) %>%
  relocate(sender_competence_f, .after = sender_competence) %>%
  relocate(sender_warmth_f, .after = sender_warmth) %>%
  relocate(quality_relationship_f, .after = quality_relationship)

# Remove fillers and rows related to non-aoi
df <- df %>% dplyr::filter(filler == 0, !is.na(congruency))

# Remove participants
to_exclude <- df %>%
  filter(
    ## To be eligible for this study, participants must be fluent European Portuguese speakers
    fluency_pt > 5 & nationality == 2 
    ## Given that the majority of the sample self-identified as White, 
    ## we restricted our analysis to this demographic
    | racial_groups == "negro") %>%
  dplyr::select(id) %>%
  distinct() %>%
  pull()

print(to_exclude)
[1] "s013" "s014" "s064" "s070"
df <- df %>%
  filter(!(id %in% to_exclude))

# Check participants
length(unique(df$id)) # 76 participants
[1] 76
# Remove trials with reading time over 2 minutes
df$rt_key_conversat[df$rt_key_conversat > 120000] <- NA

# Remove columns that contain only missing values (NA) for all rows
df <- df[,colSums(is.na(df))<nrow(df)]

# Reformat id
df <- df %>% mutate(id = as.numeric(sub("s0*", "", id)))

# Scale numerical control variables
variables <- c("texting_usage", "emoji_usage1", "emoji_usage2", "skin_color_id", 
               "identification_level", "cross1_white_nr", "cross2_white_nr", "att_mean", 
               "inj_white", "inj_black", "inj_yellow", "inj_should_1", "inj_importance", 
               "inj_importance", "descriptive_norm", "skin_tone_emoji_id", 
               "usage_skintone1", "usage_skintone2", "politic_left_right")
scaled_variables <- paste0(variables, "_s")
df[scaled_variables] <- scale(df[variables])

# Determine predictors' reference levels
df$emoji_color <- factor(df$emoji_color, levels = c("yellow", # reference level
                                                    "dark",
                                                    "light"))

df$profile_pic <- factor(df$profile_pic, levels = c("neutral", # reference level
                                                    "black",
                                                    "white"))

df$condition <- factor(
  df$condition,
  levels = c(
    "neutralpic_yellowemoji",
    "neutralpic_darkemoji",
    "neutralpic_lightemoji",
    "blackpic_yellowemoji",
    "blackpic_darkemoji",
    "blackpic_lightemoji",
    "whitepic_yellowemoji",
    "whitepic_darkemoji",
    "whitepic_lightemoji"
  )
)

rm(to_exclude, credit_ids, scaled_variables, variables)

save(df, file = "001_merged_and_cleaned_data.RData")
write_csv(df, "001_merged_and_cleaned_data.csv")

Descriptive Analysis

# Prepare data so there is one row per participant
x_socio <- df[!duplicated(df$id), ]

# View racialized identity descriptives; White = branco
table(x_socio$racial_groups)

branco 
    76 
# View gender descriptive; 0 = male; 1 = female; 9 = other
table(x_socio$gender) # 57 female; 18 male; 1 other

 0  1  9 
18 57  1 
percent.table(x_socio$gender)
x
        0         1         9 
23.684211 75.000000  1.315789 
# View age descriptive; M = 24.22, SD = 10.24, 18-64
summary(x_socio$age)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  18.00   19.00   21.00   24.22   22.25   64.00 
sd(x_socio$age)
[1] 10.23536
# View nationality descriptive
percent.table(x_socio$nationality)
x
        1         2 
98.684211  1.315789 
# View professional occupation descriptive; 1 = Student; 2 = Working-student
percent.table(x_socio$occupation)
x
        1         2         3         8 
80.263158 14.473684  3.947368  1.315789 
# View education descriptive; 2 = Secondary Education completed (10th to 12th grade)
percent.table(x_socio$education)
x
        2         3         4         5 
63.157895  1.315789 27.631579  7.894737 
# View volunteer descriptive
table(x_socio$volunteer)

   credit volunteer 
       31        45 
# View texting_usage descriptive
summary(x_socio$texting_usage)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   6.00   62.25   77.50   71.22   91.00  100.00 
sd(x_socio$texting_usage)
[1] 27.20765
hist_boxplot(x_socio$texting_usage,col = "lightblue",freq = TRUE,density = FALSE)

# View skin_tone_usage descriptive
percent.table(x_socio$skin_tone_usage)
x
       0        1 
14.47368 85.52632 
# View skin_color_id descriptive
table(x_socio$skin_color_id)

 1  2  3 
31 38  7 
percent.table(x_socio$skin_color_id)
x
        1         2         3 
40.789474 50.000000  9.210526 
# View skin_tone_emoji_id descriptive
table(x_socio$skin_tone_emoji_id)

 1  2  3  4  5 
27 28  5  1  4 
sum(is.na(x_socio$skin_tone_emoji_id))
[1] 11
x_socio_cleaned <- x_socio[!is.na(x_socio$skin_tone_emoji_id), ]
percent.table(x_socio_cleaned$skin_tone_emoji_id)
x
        1         2         3         4         5 
41.538462 43.076923  7.692308  1.538462  6.153846 
# View cross1_white descriptive
table(x_socio$cross1_white)

  five to ten more than ten          none           one   two to five 
           12             6             9             9            39 
sum(is.na(x_socio$cross1_white))
[1] 1
x_socio_cleaned <- x_socio[!is.na(x_socio$cross1_white), ]
percent.table(x_socio_cleaned$cross1_white)
x
  five to ten more than ten          none           one   two to five 
           16             8            12            12            52 
# View cross2_white descriptive
table(x_socio$cross2_white)

all the time   many times occasionally    sometimes 
           7           24           20           15 
sum(is.na(x_socio$cross2_white))
[1] 10
x_socio_cleaned <- x_socio[!is.na(x_socio$cross2_white), ]
percent.table(x_socio_cleaned$cross2_white)
x
all the time   many times occasionally    sometimes 
    10.60606     36.36364     30.30303     22.72727 
# Print Supplemental Information Table
x_socio_tab <-
  st(
    x_socio,
    vars = c("age",
      "texting_usage",
      "emoji_usage1",
      "emoji_usage2",
      "identification_level",
      "att_matrix_1",
      "att_matrix_2",
      "att_matrix_3",
      "att_matrix_4",
      "att_matrix_5",
      "att_matrix_6",
      "att_mean",
      "inj_white",
      "inj_black",
      "inj_yellow",
      "inj_should_1",
      "inj_importance",
      "descriptive_norm",
      "usage_skintone1",
      "usage_skintone2",
      "politic_left_right",
      "emoji_influence"
    ),
    digits = 4,
    summ = list(c('min(x)', 'max(x)','notNA(x)','mean(x)','median(x)', 'sd(x)')),
    summ.names = list(c('Min', 'Max','notNA','Mean','Median', 'SD'))  )
x_socio_tab
Summary Statistics
Variable Min Max notNA Mean Median SD
age 18 64 76 24.22 21 10.24
texting_usage 6 100 76 71.22 77.5 27.21
emoji_usage1 2 7 76 4.697 5 1.461
emoji_usage2 2 7 76 4.921 5 1.208
identification_level 3 7 76 6.197 7 1.02
att_matrix_1 1 7 76 4.342 4 1.26
att_matrix_2 1 7 76 4.421 4 1.246
att_matrix_3 1 7 76 4.5 4 1.4
att_matrix_4 1 7 76 4.355 4 1.163
att_matrix_5 1 7 76 4.487 4 1.545
att_matrix_6 1 7 76 4.316 4 1.134
att_mean 1 7 76 4.404 4.167 1.09
inj_white 1 7 76 5.684 6 1.507
inj_black 1 7 76 3.737 4 1.962
inj_yellow 1 7 76 5.566 6 1.552
inj_should_1 1 7 76 4.276 4 1.103
inj_importance 1 7 76 3.039 3 1.579
descriptive_norm 1 7 76 4.711 5 1.719
usage_skintone1 1 7 65 3.523 3 1.778
usage_skintone2 1 7 76 3.829 4 1.587
politic_left_right 1 10 66 4.712 5 2.118
emoji_influence 1 7 76 2.908 2 2.034
# Reliability
att_scale <- df %>% dplyr::select("att_matrix_1",
      "att_matrix_2",
      "att_matrix_3",
      "att_matrix_4",
      "att_matrix_5",
      "att_matrix_6")
reliability(att_scale)
Measures of reliability 
reliability(keys = att_scale)
          omega_h alpha omega.tot  Uni  tau cong max.split min.split mean.r med.r n.items
All_items    0.78  0.92      0.94 0.98 0.98 0.99      0.94      0.87   0.65  0.63       6
rm(x_socio, x_socio_tab, x_socio_cleaned, att_scale)

Main Analysis

# Dataframes
dfp <- df %>% 
  dplyr::filter(ia_label == "aoi_photo")

dfe <- df %>% 
  dplyr::filter(ia_label == "aoi_emoji")

# Define colors for the plots
colors <- c("#003366","#5d97c7","#FFC325")

Senders Warmth

# General distribution
hist_boxplot(dfp$sender_warmth, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(dfp, aes(x = sender_warmth)) + 
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") + 
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

# ANOVA model did not fail the assumption of normally distributed residuals
anova_model <- 
  aov(sender_warmth ~ profile_pic * emoji_color + emoji_hand_type + texting_usage_s + Error(id),
      data = dfp)
residuals_anova <- anova_model$Within$residuals
qqPlot(residuals_anova)

161 157 
159 155 

Model

# Unlike linear mixed models or ANOVAs, which treat the ordinal data as continuous,
# CLMM reduces the assumptions about equal spacing between ordinal levels
# and provide more precise estimates of effects.

# Fit check
sw_logit <-
  clmm(
    sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible")

sw_clog <-
  clmm(
    sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    link = "cloglog",
    Hess = TRUE,
    nAGQ = 10)

sw_prob <-
  clmm(
    sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    link = "probit",
    Hess = TRUE,
    nAGQ = 10)

## Compare models: sw_logit had higher performance
compare_performance(sw_prob, sw_clog, sw_logit, rank = T)
# Comparison of Model Performance Indices

Name     | Model |  RMSE | Sigma | AIC weights | BIC weights | Performance-Score
--------------------------------------------------------------------------------
sw_logit |  clmm | 4.672 | 1.814 |       0.985 |       0.985 |            94.58%
sw_prob  |  clmm | 4.683 | 1.000 |       0.015 |       0.015 |            36.08%
sw_clog  |  clmm | 4.692 | 4.755 |    2.98e-06 |    2.98e-06 |             0.00%
# Compare model with and without interaction

## Model without interaction
sender_warmth_base <-
  clmm(
    sender_warmth_f ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Check effects
RVAideMemoire::Anova.clmm(sender_warmth_base, type = "2")
Analysis of Deviance Table (Type II tests)

Response: sender_warmth_f
                LR Chisq Df       Pr(>Chisq)    
emoji_color        2.447  2          0.29427    
profile_pic        2.181  2          0.33599    
emoji_hand_type   48.903  2 0.00000000002404 ***
texting_usage_s    3.400  1          0.06521 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Model with interaction
sender_warmth_int <-
  clmm(
    sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Check effects
RVAideMemoire::Anova.clmm(sender_warmth_int, type = "3")
Analysis of Deviance Table (Type III tests)

Response: sender_warmth_f
                        LR Chisq Df       Pr(>Chisq)    
emoji_color                0.000  2        1.0000000    
profile_pic                0.000  2        1.0000000    
emoji_hand_type           47.099  2 0.00000000005922 ***
texting_usage_s            3.534  1        0.0601252 .  
emoji_color:profile_pic   20.731  4        0.0003579 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check comparison
anova(sender_warmth_base, sender_warmth_int)  
Likelihood ratio tests of cumulative link models:
 
                   formula:                                                                                       link: threshold:
sender_warmth_base sender_warmth_f ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1 | id) logit flexible  
sender_warmth_int  sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id) logit flexible  

                   no.par    AIC  logLik LR.stat df Pr(>Chisq)    
sender_warmth_base     14 1932.0 -951.98                          
sender_warmth_int      18 1919.2 -941.61  20.732  4  0.0003579 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
tab_model(sender_warmth_int, 
        # file = "sender_warmth_int.doc",
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL,
          string.stat = "z",
          string.se = "SE",
          string.ci = "95% CI",
          string.est = "Log-Odds"
          )
  sender warmth f
Predictors Log-Odds SE 95% CI z p
1|2 -6.00 0.77 -7.51 – -4.49 -7.79 <0.001
2|3 -3.94 0.40 -4.72 – -3.17 -9.93 <0.001
3|4 -2.22 0.31 -2.82 – -1.62 -7.23 <0.001
4|5 0.01 0.29 -0.55 – 0.57 0.04 0.967
5|6 1.87 0.29 1.30 – 2.45 6.37 <0.001
6|7 4.28 0.34 3.61 – 4.95 12.48 <0.001
emoji color [dark] 0.29 0.32 -0.33 – 0.91 0.92 0.360
emoji color [light] 1.03 0.32 0.41 – 1.65 3.25 0.001
profile pic [black] 0.33 0.31 -0.29 – 0.94 1.05 0.295
profile pic [white] 0.38 0.31 -0.24 – 0.99 1.20 0.228
emoji hand type [peace] -0.04 0.18 -0.39 – 0.32 -0.22 0.826
emoji hand type [thumbs] 1.17 0.20 0.78 – 1.56 5.93 <0.001
texting usage s 0.28 0.15 -0.01 – 0.57 1.90 0.058
emoji color [dark] ×
profile pic [black]
0.43 0.45 -0.44 – 1.31 0.98 0.329
emoji color [light] ×
profile pic [black]
-1.24 0.45 -2.12 – -0.37 -2.79 0.005
emoji color [dark] ×
profile pic [white]
-0.62 0.44 -1.48 – 0.23 -1.43 0.153
emoji color [light] ×
profile pic [white]
-1.04 0.44 -1.90 – -0.18 -2.38 0.017
Random Effects
σ2 3.29
τ00 id 1.27
ICC 0.28
N id 76
Observations 684
Marginal R2 / Conditional R2 0.095 / 0.348
AIC 1919.230

Compare full model

# Compare parsimonious model with full model

## Remove missing values from the dataframe in order to compare models
dfp_clean <- dfp %>% dplyr::select(sender_warmth_f, emoji_color, profile_pic, emoji_hand_type, texting_usage_s, emoji_usage1_s, emoji_usage2_s, skin_color_id_s, identification_level_s, cross1_white_nr_s, cross2_white_nr_s, att_mean_s, inj_white_s, inj_black_s, inj_yellow_s, inj_should_1_s, inj_importance_s, descriptive_norm_s, skin_tone_emoji_id_s, usage_skintone1_s, usage_skintone2_s, politic_left_right_s, id) %>% drop_na()

## Model with all variables
sw_full <-
  clmm(
    sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id),
    data = dfp_clean,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Parsimonious model with cleaned dataframe
sw_parsimonious <-
  clmm(
    sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp_clean,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Compare models:
anova(sw_parsimonious, sw_full)
Likelihood ratio tests of cumulative link models:
 
                formula:                                                                                                                                                                                                                                                                                                                                                                                                                                      link: threshold:
sw_parsimonious sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id)                                                                                                                                                                                                                                                                                                                                                logit flexible  
sw_full         sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id) logit flexible  

                no.par    AIC  logLik LR.stat df Pr(>Chisq)
sw_parsimonious     18 1407.3 -685.66                      
sw_full             35 1422.6 -676.32  18.694 17     0.3464

Quality check

# Multicollinearity for categorical predictors with an interaction
sw_multi <- lm(sender_warmth ~ emoji_color * profile_pic + emoji_hand_type + texting_usage_s, 
               data = dfp)
car::vif(sw_multi, type = "predictor")
                    GVIF Df GVIF^(1/(2*Df)) Interacts With                          Other Predictors
emoji_color     1.402264  8        1.021355    profile_pic          emoji_hand_type, texting_usage_s
profile_pic     1.402264  8        1.021355    emoji_color          emoji_hand_type, texting_usage_s
emoji_hand_type 1.402264  2        1.088197           --   emoji_color, profile_pic, texting_usage_s
texting_usage_s 1.000000  1        1.000000           --   emoji_color, profile_pic, emoji_hand_type
# Random effects' normality
sw_random_effects <- as.vector(ranef(sender_warmth_int)$id$`(Intercept)`)
qqPlot(sw_random_effects)

[1] 36  2
# Proportional odds assumption
sw_clm <-
  clm(
    sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s,
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

nominal_test(sw_clm)
Tests of nominal effects

formula: sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s
                        Df  logLik    AIC     LRT Pr(>Chi)
<none>                     -991.58 2017.2                 
emoji_color             10 -987.04 2028.1  9.0960   0.5230
profile_pic             10 -985.77 2025.5 11.6200   0.3113
emoji_hand_type                                           
texting_usage_s          5 -989.83 2023.7  3.5083   0.6221
emoji_color:profile_pic                                   
scale_test(sw_clm)
Tests of scale effects

formula: sender_warmth_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s
                        Df  logLik    AIC     LRT Pr(>Chi)
<none>                     -991.58 2017.2                 
emoji_color              2 -991.14 2020.3  0.8810   0.6437
profile_pic              2 -989.90 2017.8  3.3622   0.1862
emoji_hand_type          2 -991.42 2020.8  0.3304   0.8477
texting_usage_s          1 -991.29 2018.6  0.5833   0.4450
emoji_color:profile_pic  8 -986.52 2023.0 10.1383   0.2555
# Harrell Plot
table(dfp$sender_warmth) # the minimum response registered was "1"

  1   2   3   4   5   6   7 
  2  12  46 189 230 166  39 
sw_func <- function(y) {
  c(
    'Y>=1' = qlogis(mean(y >= 1)),
    'Y>=2' = qlogis(mean(y >= 2)),
    'Y>=3' = qlogis(mean(y >= 3)),
    'Y>=4' = qlogis(mean(y >= 4)),
    'Y>=5' = qlogis(mean(y >= 5)),
    'Y>=6' = qlogis(mean(y >= 6)),
    'Y>=7' = qlogis(mean(y >= 7))
  )
}

sw_sf <-
  with(
    dfp,
    summary(
      sender_warmth_f ~ emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
      fun = sw_func
    )
  )
sw_sf
sender_warmth_f      N= 684  

+---------------+---------------+---+----+--------+--------+--------+---------+----------+---------+
|               |               |  N|Y>=1|    Y>=2|    Y>=3|    Y>=4|     Y>=5|      Y>=6|     Y>=7|
+---------------+---------------+---+----+--------+--------+--------+---------+----------+---------+
|    emoji_color|         yellow|228| Inf|5.424950|3.797734|2.140066|0.4643056|-0.7529657|-2.726919|
|               |           dark|228| Inf|     Inf|4.727388|2.583998|0.6344985|-0.6931472|-2.653242|
|               |          light|228| Inf|5.424950|3.452253|2.341806|0.5768874|-1.1221428|-3.081910|
+---------------+---------------+---+----+--------+--------+--------+---------+----------+---------+
|    profile_pic|        neutral|228| Inf|5.424950|3.610918|2.236834|0.5014798|-0.6344985|-2.805689|
|               |          black|228| Inf|5.424950|3.797734|2.341806|0.6734744|-0.7935659|-2.726919|
|               |          white|228| Inf|     Inf|4.317488|2.456736|0.5014798|-1.1459584|-2.890372|
+---------------+---------------+---+----+--------+--------+--------+---------+----------+---------+
|emoji_hand_type|             ok|228| Inf|5.424950|4.025352|2.007468|0.3908663|-1.1700713|-3.314186|
|               |          peace|228| Inf|5.424950|3.081910|2.187516|0.2468601|-1.2697605|-3.191847|
|               |         thumbs|228| Inf|     Inf|     Inf|3.081910|1.0986123|-0.2290666|-2.236834|
+---------------+---------------+---+----+--------+--------+--------+---------+----------+---------+
|texting_usage_s|[-2.412,-0.304)|171| Inf|     Inf|3.731699|2.341806|0.3184537|-1.1221428|-3.731699|
|               |[-0.304, 0.325)|171| Inf|4.436752|3.502550|2.203739|0.7462570|-0.6409614|-2.778819|
|               |[ 0.325, 0.768)|180| Inf|     Inf|3.784190|1.971553|0.6435502|-0.7435780|-2.327278|
|               |[ 0.768, 1.064]|162| Inf|     Inf|5.081404|3.258097|0.5306283|-0.9249488|-2.833213|
+---------------+---------------+---+----+--------+--------+--------+---------+----------+---------+
|         1 | id|           TRUE|684| Inf|5.831882|3.868220|2.341806|0.5578931|-0.8486906|-2.805689|
+---------------+---------------+---+----+--------+--------+--------+---------+----------+---------+
|        Overall|               |684| Inf|5.831882|3.868220|2.341806|0.5578931|-0.8486906|-2.805689|
+---------------+---------------+---+----+--------+--------+--------+---------+----------+---------+
plot(
  sw_sf,
  which = 1:7,
  pch = 1:7,
  xlab = 'logit',
  main = 'Harrell Plot',
  xlim = range(-4, 6.5)
)

Post-hoc comparisons

# Calculate the predicted values
sw_emm <- emmeans(sender_warmth_int, ~ emoji_color * profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(sw_emm, by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral -0.4389595 0.1808033 0.95 -0.7933275 -0.0845916 -2.4278292 Inf 0.0455685
dark effect neutral -0.1497614 0.1860576 0.95 -0.5144276 0.2149048 -0.8049196 Inf 0.5411135
light effect neutral 0.5887210 0.1863964 0.95 0.2233907 0.9540513 3.1584346 Inf 0.0071379
yellow effect black -0.1693873 0.1846527 0.95 -0.5313000 0.1925254 -0.9173289 Inf 0.5384555
dark effect black 0.5548030 0.1748910 0.95 0.2120229 0.8975831 3.1722785 Inf 0.0071379
light effect black -0.3854157 0.1859447 0.95 -0.7498605 -0.0209709 -2.0727442 Inf 0.0859412
yellow effect white 0.1160470 0.1758500 0.95 -0.2286127 0.4607067 0.6599203 Inf 0.5462005
dark effect white -0.2195460 0.1723711 0.95 -0.5573873 0.1182952 -1.2736821 Inf 0.3649970
light effect white 0.1034990 0.1715084 0.95 -0.2326513 0.4396494 0.6034634 Inf 0.5462005
# View how contrasts were calculated
# the columns should be read vertically
coef(emmeans::contrast(sw_emm, by = "profile_pic")) 
  emoji_color profile_pic        c.1        c.2        c.3        c.4        c.5        c.6        c.7        c.8        c.9
1      yellow     neutral  0.6666667 -0.3333333 -0.3333333  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000
2        dark     neutral -0.3333333  0.6666667 -0.3333333  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000
3       light     neutral -0.3333333 -0.3333333  0.6666667  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000
4      yellow       black  0.0000000  0.0000000  0.0000000  0.6666667 -0.3333333 -0.3333333  0.0000000  0.0000000  0.0000000
5        dark       black  0.0000000  0.0000000  0.0000000 -0.3333333  0.6666667 -0.3333333  0.0000000  0.0000000  0.0000000
6       light       black  0.0000000  0.0000000  0.0000000 -0.3333333 -0.3333333  0.6666667  0.0000000  0.0000000  0.0000000
7      yellow       white  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.6666667 -0.3333333 -0.3333333
8        dark       white  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000 -0.3333333  0.6666667 -0.3333333
9       light       white  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000 -0.3333333 -0.3333333  0.6666667
model_parameters(
  emmeans::contrast(sw_emm, by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral effect yellow -0.2352054 0.1819720 0.95 -0.5918640 0.1214531 -1.2925364 Inf 0.3531086
black effect yellow 0.0925933 0.1788965 0.95 -0.2580374 0.4432240 0.5175803 Inf 0.6047511
white effect yellow 0.1426121 0.1790751 0.95 -0.2083687 0.4935929 0.7963815 Inf 0.4912694
neutral effect dark -0.1719391 0.1788332 0.95 -0.5224457 0.1785676 -0.9614494 Inf 0.4912694
black effect dark 0.5908518 0.1767422 0.95 0.2444435 0.9372601 3.3430154 Inf 0.0074586
white effect dark -0.4189127 0.1737063 0.95 -0.7593708 -0.0784546 -2.4116149 Inf 0.0476461
neutral effect light 0.5261070 0.1765510 0.95 0.1800734 0.8721407 2.9799147 Inf 0.0129748
black effect light -0.3898032 0.1782261 0.95 -0.7391199 -0.0404864 -2.1871271 Inf 0.0646498
white effect light -0.1363039 0.1752417 0.95 -0.4797713 0.2071635 -0.7778051 Inf 0.4912694
# View how contrasts were calculated
# the columns should be read vertically
coef(emmeans::contrast(sw_emm, by = "emoji_color")) 
  emoji_color profile_pic        c.1        c.2        c.3        c.4        c.5        c.6        c.7        c.8        c.9
1      yellow     neutral  0.6666667 -0.3333333 -0.3333333  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000
2        dark     neutral  0.0000000  0.0000000  0.0000000  0.6666667 -0.3333333 -0.3333333  0.0000000  0.0000000  0.0000000
3       light     neutral  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.6666667 -0.3333333 -0.3333333
4      yellow       black -0.3333333  0.6666667 -0.3333333  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000
5        dark       black  0.0000000  0.0000000  0.0000000 -0.3333333  0.6666667 -0.3333333  0.0000000  0.0000000  0.0000000
6       light       black  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000 -0.3333333  0.6666667 -0.3333333
7      yellow       white -0.3333333 -0.3333333  0.6666667  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000
8        dark       white  0.0000000  0.0000000  0.0000000 -0.3333333 -0.3333333  0.6666667  0.0000000  0.0000000  0.0000000
9       light       white  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000  0.0000000 -0.3333333 -0.3333333  0.6666667
##  Emmeans explains the interaction contrasts process as follow: "Contrasts are
##  generated for each factor separately, one at a time; and these contrasts
##  are applied to the object (the first time around) or to the previous
##  result (subsequently). The final result comprises contrasts of contrasts,
##  or, equivalently, products of contrasts for the factors involved".
model_parameters(
  emmeans::contrast(sw_emm, interaction = TRUE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
emoji_color_eff profile_pic_eff Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral effect -0.2748596 0.1472638 0.95 -0.5634913 0.0137721 -1.8664443 Inf 0.0929688
dark effect neutral effect -0.2115933 0.1488406 0.95 -0.5033155 0.0801290 -1.4216096 Inf 0.1994652
light effect neutral effect 0.4864529 0.1474258 0.95 0.1975035 0.7754022 3.2996446 Inf 0.0029042
yellow effect black effect -0.0052873 0.1485241 0.95 -0.2963893 0.2858146 -0.0355991 Inf 0.9932426
dark effect black effect 0.4929711 0.1448978 0.95 0.2089766 0.7769657 3.4021981 Inf 0.0029042
light effect black effect -0.4876838 0.1473929 0.95 -0.7765686 -0.1987990 -3.3087328 Inf 0.0029042
yellow effect white effect 0.2801469 0.1456281 0.95 -0.0052789 0.5655728 1.9237149 Inf 0.0929688
dark effect white effect -0.2813779 0.1427028 0.95 -0.5610702 -0.0016856 -1.9717760 Inf 0.0929688
light effect white effect 0.0012309 0.1453437 0.95 -0.2836374 0.2860993 0.0084692 Inf 0.9932426
# View how interaction contrasts were calculated
# the columns should be read vertically
coef(emmeans::contrast(sw_emm, interaction = TRUE)) 
  emoji_color profile_pic        c.1        c.2        c.3        c.4        c.5        c.6        c.7        c.8        c.9
1      yellow     neutral  0.4444444 -0.2222222 -0.2222222 -0.2222222  0.1111111  0.1111111 -0.2222222  0.1111111  0.1111111
2        dark     neutral -0.2222222  0.4444444 -0.2222222  0.1111111 -0.2222222  0.1111111  0.1111111 -0.2222222  0.1111111
3       light     neutral -0.2222222 -0.2222222  0.4444444  0.1111111  0.1111111 -0.2222222  0.1111111  0.1111111 -0.2222222
4      yellow       black -0.2222222  0.1111111  0.1111111  0.4444444 -0.2222222 -0.2222222 -0.2222222  0.1111111  0.1111111
5        dark       black  0.1111111 -0.2222222  0.1111111 -0.2222222  0.4444444 -0.2222222  0.1111111 -0.2222222  0.1111111
6       light       black  0.1111111  0.1111111 -0.2222222 -0.2222222 -0.2222222  0.4444444  0.1111111  0.1111111 -0.2222222
7      yellow       white -0.2222222  0.1111111  0.1111111 -0.2222222  0.1111111  0.1111111  0.4444444 -0.2222222 -0.2222222
8        dark       white  0.1111111 -0.2222222  0.1111111  0.1111111 -0.2222222  0.1111111 -0.2222222  0.4444444 -0.2222222
9       light       white  0.1111111  0.1111111 -0.2222222  0.1111111  0.1111111 -0.2222222 -0.2222222 -0.2222222  0.4444444
model_parameters(
  emmeans::contrast(sw_emm, "pairwise", by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow - dark neutral -0.2891981 0.3160236 0.95 -0.9085930 0.3301967 -0.9151157 Inf 0.4630255
yellow - light neutral -1.0276805 0.3166220 0.95 -1.6482483 -0.4071127 -3.2457644 Inf 0.0105422
dark - light neutral -0.7384824 0.3256260 0.95 -1.3766976 -0.1002671 -2.2678851 Inf 0.0525065
yellow - dark black -0.7241903 0.3078824 0.95 -1.3276287 -0.1207519 -2.3521652 Inf 0.0525065
yellow - light black 0.2160284 0.3267372 0.95 -0.4243648 0.8564217 0.6611687 Inf 0.5720671
dark - light black 0.9402187 0.3102063 0.95 0.3322256 1.5482118 3.0309468 Inf 0.0109705
yellow - dark white 0.3355930 0.3030758 0.95 -0.2584246 0.9296107 1.1072908 Inf 0.4114919
yellow - light white 0.0125479 0.3016039 0.95 -0.5785848 0.6036807 0.0416041 Inf 0.9668143
dark - light white -0.3230451 0.2955176 0.95 -0.9022490 0.2561588 -1.0931500 Inf 0.4114919
# View how contrasts were calculated
# the columns should be read vertically
coef(emmeans::contrast(sw_emm, "pairwise", by = "profile_pic")) 
  emoji_color profile_pic c.1 c.2 c.3 c.4 c.5 c.6 c.7 c.8 c.9
1      yellow     neutral   1   1   0   0   0   0   0   0   0
2        dark     neutral  -1   0   1   0   0   0   0   0   0
3       light     neutral   0  -1  -1   0   0   0   0   0   0
4      yellow       black   0   0   0   1   1   0   0   0   0
5        dark       black   0   0   0  -1   0   1   0   0   0
6       light       black   0   0   0   0  -1  -1   0   0   0
7      yellow       white   0   0   0   0   0   0   1   1   0
8        dark       white   0   0   0   0   0   0  -1   0   1
9       light       white   0   0   0   0   0   0   0  -1  -1
model_parameters(
  emmeans::contrast(sw_emm, "pairwise", by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral - black yellow -0.3277987 0.3133172 0.95 -0.9418891 0.2862916 -1.0462202 Inf 0.4431891
neutral - white yellow -0.3778175 0.3136231 0.95 -0.9925075 0.2368724 -1.2046866 Inf 0.4109838
black - white yellow -0.0500188 0.3082692 0.95 -0.6542153 0.5541778 -0.1622568 Inf 0.8711036
neutral - black dark -0.7627909 0.3102649 0.95 -1.3708990 -0.1546828 -2.4585145 Inf 0.0418539
neutral - white dark 0.2469736 0.3050780 0.95 -0.3509683 0.8449156 0.8095426 Inf 0.4704785
black - white dark 1.0097645 0.3014001 0.95 0.4190311 1.6004979 3.3502458 Inf 0.0072666
neutral - black light 0.9159102 0.3084801 0.95 0.3113003 1.5205202 2.9691061 Inf 0.0134400
neutral - white light 0.6624109 0.3033073 0.95 0.0679396 1.2568822 2.1839600 Inf 0.0651717
black - white light -0.2534993 0.3062321 0.95 -0.8537033 0.3467047 -0.8278010 Inf 0.4704785
# View how contrasts were calculated
# the columns should be read vertically
coef(emmeans::contrast(sw_emm, "pairwise", by = "emoji_color")) 
  emoji_color profile_pic c.1 c.2 c.3 c.4 c.5 c.6 c.7 c.8 c.9
1      yellow     neutral   1   1   0   0   0   0   0   0   0
2        dark     neutral   0   0   0   1   1   0   0   0   0
3       light     neutral   0   0   0   0   0   0   1   1   0
4      yellow       black  -1   0   1   0   0   0   0   0   0
5        dark       black   0   0   0  -1   0   1   0   0   0
6       light       black   0   0   0   0   0   0  -1   0   1
7      yellow       white   0  -1  -1   0   0   0   0   0   0
8        dark       white   0   0   0   0  -1  -1   0   0   0
9       light       white   0   0   0   0   0   0   0  -1  -1
model_parameters(
  emmeans::contrast(sw_emm, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow neutral - dark neutral -0.2891981 0.3160236 0.95 -0.9085930 0.3301967 -0.9151157 Inf 0.6173673
yellow neutral - light neutral -1.0276805 0.3166220 0.95 -1.6482483 -0.4071127 -3.2457644 Inf 0.0114222
yellow neutral - yellow black -0.3277987 0.3133172 0.95 -0.9418891 0.2862916 -1.0462202 Inf 0.5598178
yellow neutral - dark black -1.0519890 0.3121176 0.95 -1.6637283 -0.4402496 -3.3704887 Inf 0.0114222
yellow neutral - light black -0.1117703 0.3179662 0.95 -0.7349725 0.5114319 -0.3515163 Inf 0.9540584
yellow neutral - yellow white -0.3778175 0.3136231 0.95 -0.9925075 0.2368724 -1.2046866 Inf 0.5255416
yellow neutral - dark white -0.0422245 0.3073453 0.95 -0.6446102 0.5601612 -0.1373845 Inf 0.9540584
yellow neutral - light white -0.3652696 0.3066393 0.95 -0.9662716 0.2357325 -1.1912026 Inf 0.5255416
dark neutral - light neutral -0.7384824 0.3256260 0.95 -1.3766976 -0.1002671 -2.2678851 Inf 0.0802113
dark neutral - yellow black -0.0386006 0.3050144 0.95 -0.6364178 0.5592166 -0.1265534 Inf 0.9540584
dark neutral - dark black -0.7627909 0.3102649 0.95 -1.3708990 -0.1546828 -2.4585145 Inf 0.0717496
dark neutral - light black 0.1774278 0.3217040 0.95 -0.4531004 0.8079561 0.5515251 Inf 0.8048406
dark neutral - yellow white -0.0886194 0.3116937 0.95 -0.6995278 0.5222890 -0.2843156 Inf 0.9540584
dark neutral - dark white 0.2469736 0.3050780 0.95 -0.3509683 0.8449156 0.8095426 Inf 0.6273047
dark neutral - light white -0.0760714 0.3042986 0.95 -0.6724858 0.5203429 -0.2499894 Inf 0.9540584
light neutral - yellow black 0.6998818 0.3178206 0.95 0.0769648 1.3227987 2.2021283 Inf 0.0802113
light neutral - dark black -0.0243085 0.3049942 0.95 -0.6220861 0.5734692 -0.0797015 Inf 0.9632311
light neutral - light black 0.9159102 0.3084801 0.95 0.3113003 1.5205202 2.9691061 Inf 0.0179200
light neutral - yellow white 0.6498630 0.3100584 0.95 0.0421596 1.2575664 2.0959371 Inf 0.0927971
light neutral - dark white 0.9854560 0.3057697 0.95 0.3861585 1.5847536 3.2228704 Inf 0.0114222
light neutral - light white 0.6624109 0.3033073 0.95 0.0679396 1.2568822 2.1839600 Inf 0.0802113
yellow black - dark black -0.7241903 0.3078824 0.95 -1.3276287 -0.1207519 -2.3521652 Inf 0.0802113
yellow black - light black 0.2160284 0.3267372 0.95 -0.4243648 0.8564217 0.6611687 Inf 0.7322459
yellow black - yellow white -0.0500188 0.3082692 0.95 -0.6542153 0.5541778 -0.1622568 Inf 0.9540584
yellow black - dark white 0.2855742 0.3025947 0.95 -0.3075005 0.8786489 0.9437517 Inf 0.6173673
yellow black - light white -0.0374708 0.3013856 0.95 -0.6281757 0.5532340 -0.1243286 Inf 0.9540584
dark black - light black 0.9402187 0.3102063 0.95 0.3322256 1.5482118 3.0309468 Inf 0.0175528
dark black - yellow white 0.6741715 0.3067475 0.95 0.0729574 1.2753856 2.1978058 Inf 0.0802113
dark black - dark white 1.0097645 0.3014001 0.95 0.4190311 1.6004979 3.3502458 Inf 0.0114222
dark black - light white 0.6867194 0.2993870 0.95 0.0999317 1.2735072 2.2937516 Inf 0.0802113
light black - yellow white -0.2660472 0.3140678 0.95 -0.8816089 0.3495144 -0.8471012 Inf 0.6273047
light black - dark white 0.0695458 0.3071378 0.95 -0.5324332 0.6715248 0.2264319 Inf 0.9540584
light black - light white -0.2534993 0.3062321 0.95 -0.8537033 0.3467047 -0.8278010 Inf 0.6273047
yellow white - dark white 0.3355930 0.3030758 0.95 -0.2584246 0.9296107 1.1072908 Inf 0.5486559
yellow white - light white 0.0125479 0.3016039 0.95 -0.5785848 0.6036807 0.0416041 Inf 0.9668143
dark white - light white -0.3230451 0.2955176 0.95 -0.9022490 0.2561588 -1.0931500 Inf 0.5486559
# Covariate
sw_emm_co <- emmeans(sender_warmth_int, ~ emoji_hand_type)
model_parameters(
  emmeans::contrast(sw_emm_co, "revpairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) 
contrast       | Coefficient |   SE |        95% CI |     z |      p
--------------------------------------------------------------------
peace - ok     |       -0.04 | 0.18 | [-0.39, 0.32] | -0.22 | 0.826 
thumbs - ok    |        1.17 | 0.20 | [ 0.78, 1.56] |  5.93 | < .001
thumbs - peace |        1.21 | 0.20 | [ 0.82, 1.60] |  6.10 | < .001

p-value adjustment method: Benjamini & Hochberg (1995)

Plot

# Estimated means plot

# Generate interaction-style plot for estimated marginal means
sw_plot <- emmip(sender_warmth_int, ~ emoji_color * profile_pic, CIs = TRUE, mode = "mean.class")
sw_df_p <- sw_plot$data

sw_df_p <- sw_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color),
         profile_pic = str_to_title(profile_pic))

sw_df_p$profile_pic <- factor(sw_df_p$profile_pic, levels = c("Neutral",
                                                              "Black",
                                                              "White"))
# Run plot
sender_warmth_pploto <-
  ggplot(sw_df_p, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(sw_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Profile Picture\n", y = "Estimated Warmth Ratings\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    limits = c(4.4, 5.5),
    breaks = seq(4.4, 5.5, 0.2),
    position = "right"
  ) +
  scale_color_manual(values = colors, guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 
sender_warmth_pploto

# Save plot
# ggsave(filename = "sender_warmth_pplot.svg", width = 216, height = 131, unit = "mm", dpi = 300)
rm(list = ls(pattern = "^sw_"), anova_model, residuals_anova, dfp_clean, original_range, estimated_range, scaling_factor)

Senders Competence

# General distribution
hist_boxplot(dfp$sender_competence, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(dfp, aes(x = sender_competence)) + 
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") + 
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

# ANOVA model fails the assumption of normally distributed residuals
anova_model <- 
  aov(sender_competence ~ profile_pic * emoji_color + emoji_hand_type + texting_usage_s + Error(id),
      data = dfp)
residuals_anova <- anova_model$Within$residuals
qqPlot(residuals_anova)

183 464 
181 462 

Model

# Unlike linear mixed models or ANOVAs, which treat the ordinal data as continuous,
# CLMM reduces the assumptions about equal spacing between ordinal levels
# and provide more precise estimates of effects.

# Fit check
sc_logit <-
  clmm(
    sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible")

sc_clog <-
  clmm(
    sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    link = "cloglog",
    Hess = TRUE,
    nAGQ = 10)

sc_prob <-
  clmm(
    sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    link = "probit",
    Hess = TRUE,
    nAGQ = 10)

## Compare models: sc_logit had higher performance
compare_performance(sc_prob, sc_clog, sc_logit, rank = T)
# Comparison of Model Performance Indices

Name     | Model |  RMSE | Sigma | AIC weights | BIC weights | Performance-Score
--------------------------------------------------------------------------------
sc_logit |  clmm | 4.621 | 1.814 |       1.000 |       1.000 |            94.54%
sc_prob  |  clmm | 4.644 | 1.000 |    5.10e-06 |    5.10e-06 |            37.66%
sc_clog  |  clmm | 4.669 | 4.728 |    2.71e-16 |    2.71e-16 |             0.00%
# Compare model with and without interaction

## Model without interaction
sender_competence_base <-
  clmm(
    sender_competence_f ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Check effects
RVAideMemoire::Anova.clmm(sender_competence_base, type = "2")
Analysis of Deviance Table (Type II tests)

Response: sender_competence_f
                LR Chisq Df Pr(>Chisq)  
emoji_color       0.5730  2    0.75089  
profile_pic       0.3250  2    0.85001  
emoji_hand_type   2.2902  2    0.31819  
texting_usage_s   4.8028  1    0.02841 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
tab_model(sender_competence_base, 
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL)
  sender competence f
Predictors Log-Odds std. Error CI Statistic p
2|3 -6.35 0.64 -7.61 – -5.10 -9.91 <0.001
3|4 -4.07 0.34 -4.73 – -3.41 -12.10 <0.001
4|5 -0.70 0.27 -1.23 – -0.17 -2.59 0.010
5|6 1.06 0.27 0.53 – 1.59 3.89 <0.001
6|7 3.62 0.33 2.98 – 4.26 11.07 <0.001
emoji color [dark] -0.13 0.18 -0.49 – 0.22 -0.74 0.459
emoji color [light] -0.04 0.19 -0.41 – 0.33 -0.22 0.822
profile pic [black] 0.07 0.18 -0.28 – 0.42 0.40 0.690
profile pic [white] 0.10 0.18 -0.25 – 0.45 0.55 0.580
emoji hand type [peace] 0.10 0.18 -0.26 – 0.45 0.53 0.597
emoji hand type [thumbs] -0.19 0.19 -0.55 – 0.18 -1.00 0.316
texting usage s 0.42 0.19 0.05 – 0.79 2.22 0.027
Random Effects
σ2 3.29
τ00 id 2.31
ICC 0.41
N id 76
Observations 684
Marginal R2 / Conditional R2 0.034 / 0.433
AIC 1731.072
## Model with interaction
## "emoji_color * profile_pic" is the same as "emoji_color + profile_pic + emoji_color:profile_pic"
sender_competence_int <-
  clmm(
    sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Check effects
RVAideMemoire::Anova.clmm(sender_competence_int, type = "3")
Analysis of Deviance Table (Type III tests)

Response: sender_competence_f
                        LR Chisq Df Pr(>Chisq)   
emoji_color               0.0000  2   1.000000   
profile_pic               0.0000  2   1.000000   
emoji_hand_type           1.7513  2   0.416592   
texting_usage_s           4.7943  1   0.028554 * 
emoji_color:profile_pic  16.8491  4   0.002068 **
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check comparison
anova(sender_competence_base, sender_competence_int)  
Likelihood ratio tests of cumulative link models:
 
                       formula:                                                                                           link: threshold:
sender_competence_base sender_competence_f ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1 | id) logit flexible  
sender_competence_int  sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id) logit flexible  

                       no.par    AIC  logLik LR.stat df Pr(>Chisq)   
sender_competence_base     13 1731.1 -852.54                         
sender_competence_int      17 1722.2 -844.11  16.849  4   0.002068 **
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
tab_model(sender_competence_int,
        # file = "sender_competence_int.doc",
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL,
          string.stat = "z",
          string.se = "SE",
          string.ci = "95% CI",
          string.est = "Log-Odds"
          )
  sender competence f
Predictors Log-Odds SE 95% CI z p
2|3 -6.64 0.66 -7.94 – -5.34 -9.99 <0.001
3|4 -4.35 0.38 -5.10 – -3.61 -11.48 <0.001
4|5 -0.93 0.32 -1.55 – -0.31 -2.93 0.003
5|6 0.87 0.32 0.25 – 1.49 2.77 0.006
6|7 3.48 0.36 2.76 – 4.19 9.59 <0.001
emoji color [dark] 0.03 0.32 -0.59 – 0.66 0.10 0.917
emoji color [light] -0.62 0.33 -1.26 – 0.02 -1.89 0.059
profile pic [black] -0.33 0.32 -0.96 – 0.30 -1.01 0.311
profile pic [white] 0.10 0.32 -0.52 – 0.72 0.31 0.756
emoji hand type [peace] -0.08 0.19 -0.45 – 0.29 -0.43 0.665
emoji hand type [thumbs] -0.26 0.20 -0.66 – 0.13 -1.31 0.191
texting usage s 0.43 0.19 0.05 – 0.81 2.22 0.027
emoji color [dark] ×
profile pic [black]
-0.22 0.46 -1.12 – 0.68 -0.49 0.627
emoji color [light] ×
profile pic [black]
1.44 0.46 0.53 – 2.35 3.11 0.002
emoji color [dark] ×
profile pic [white]
-0.26 0.45 -1.14 – 0.62 -0.58 0.562
emoji color [light] ×
profile pic [white]
0.30 0.45 -0.59 – 1.18 0.66 0.509
Random Effects
σ2 3.29
τ00 id 2.42
ICC 0.42
N id 76
Observations 684
Marginal R2 / Conditional R2 0.050 / 0.453
AIC 1722.223

Compare full model

# Compare parsimonious model with full model

## Remove missing values from the dataframe in order to compare models
dfp_clean <- dfp %>% dplyr::select(sender_competence_f, emoji_color, profile_pic, emoji_hand_type, texting_usage_s, emoji_usage1_s, emoji_usage2_s, skin_color_id_s, identification_level_s, cross1_white_nr_s, cross2_white_nr_s, att_mean_s, inj_white_s, inj_black_s, inj_yellow_s, inj_should_1_s, inj_importance_s, descriptive_norm_s, skin_tone_emoji_id_s, usage_skintone1_s, usage_skintone2_s, politic_left_right_s, id) %>% drop_na()

## Model with all variables
sc_full <-
  clmm(
    sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id),
    data = dfp_clean,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Parsimonious model with cleaned dataframe
sc_parsimonious <-
  clmm(
    sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp_clean,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Compare models
anova(sc_parsimonious, sc_full)
Likelihood ratio tests of cumulative link models:
 
                formula:                                                                                                                                                                                                                                                                                                                                                                                                                                          link: threshold:
sc_parsimonious sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id)                                                                                                                                                                                                                                                                                                                                                logit flexible  
sc_full         sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id) logit flexible  

                no.par    AIC  logLik LR.stat df Pr(>Chisq)
sc_parsimonious     17 1271.3 -618.67                      
sc_full             34 1289.9 -610.93  15.481 17     0.5609

Quality check

# Multicollinearity for categorical predictors with an interaction
sc_multi <- lm(sender_competence ~ emoji_color * profile_pic + emoji_hand_type + texting_usage_s, 
               data = dfp)
car::vif(sc_multi, type = "predictor") # no issues
                    GVIF Df GVIF^(1/(2*Df)) Interacts With                          Other Predictors
emoji_color     1.402264  8        1.021355    profile_pic          emoji_hand_type, texting_usage_s
profile_pic     1.402264  8        1.021355    emoji_color          emoji_hand_type, texting_usage_s
emoji_hand_type 1.402264  2        1.088197           --   emoji_color, profile_pic, texting_usage_s
texting_usage_s 1.000000  1        1.000000           --   emoji_color, profile_pic, emoji_hand_type
# Random effects' normality
sc_random_effects <- as.vector(ranef(sender_competence_int)$id$`(Intercept)`)
qqPlot(sc_random_effects) # no issues

[1] 16  2
# Proportional odds assumption
sc_clm <-
  clm(
    sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s,
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

nominal_test(sc_clm) # no issues
Tests of nominal effects

formula: sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s
                        Df  logLik    AIC     LRT Pr(>Chi)
<none>                     -936.14 1904.3                 
emoji_color              8 -934.50 1917.0  3.2669   0.9165
profile_pic              8 -933.20 1914.4  5.8691   0.6619
emoji_hand_type          8 -931.42 1910.8  9.4214   0.3080
texting_usage_s          4 -934.45 1908.9  3.3808   0.4962
emoji_color:profile_pic 32 -921.27 1938.5 29.7250   0.5822
scale_test(sc_clm) # no issues
Tests of scale effects

formula: sender_competence_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s
                        Df  logLik    AIC     LRT Pr(>Chi)
<none>                     -936.14 1904.3                 
emoji_color              2 -935.09 1906.2  2.0977   0.3503
profile_pic              2 -935.67 1907.3  0.9408   0.6248
emoji_hand_type          2 -933.99 1904.0  4.2845   0.1174
texting_usage_s          1 -935.24 1904.5  1.7987   0.1799
emoji_color:profile_pic  8 -929.99 1908.0 12.2841   0.1390
# Harrell Plot
table(dfp$sender_competence) # the minimum response registered was "2"

  2   3   4   5   6   7 
  3  25 250 200 161  45 
sc_func <- function(y) {
  c(
    'Y>=2' = qlogis(mean(y >= 2)),
    'Y>=3' = qlogis(mean(y >= 3)),
    'Y>=4' = qlogis(mean(y >= 4)),
    'Y>=5' = qlogis(mean(y >= 5)),
    'Y>=6' = qlogis(mean(y >= 6)),
    'Y>=7' = qlogis(mean(y >= 7))
  )
}

sc_sf <-
  with(
    dfp,
    summary(
      sender_competence_f ~ emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
      fun = sc_func
    )
  )
sc_sf
sender_competence_f      N= 684  

+---------------+---------------+---+----+--------+--------+----------+----------+---------+
|               |               |  N|Y>=2|    Y>=3|    Y>=4|      Y>=5|      Y>=6|     Y>=7|
+---------------+---------------+---+----+--------+--------+----------+----------+---------+
|    emoji_color|         yellow|228| Inf|5.424950|2.982002| 0.3364722|-0.7529657|-2.653242|
|               |           dark|228| Inf|5.424950|3.081910| 0.3364722|-0.9193629|-2.726919|
|               |          light|228| Inf|5.424950|3.452253| 0.4643056|-0.8556661|-2.583998|
+---------------+---------------+---+----+--------+--------+----------+----------+---------+
|    profile_pic|        neutral|228| Inf|4.727388|2.982002| 0.2825670|-0.8556661|-2.726919|
|               |          black|228| Inf|5.424950|2.890372| 0.4458376|-0.8556661|-2.653242|
|               |          white|228| Inf|     Inf|3.797734| 0.4091214|-0.8140998|-2.583998|
+---------------+---------------+---+----+--------+--------+----------+----------+---------+
|emoji_hand_type|             ok|228| Inf|     Inf|3.191847| 0.4828518|-0.8767117|-2.805689|
|               |          peace|228| Inf|4.727388|3.314186| 0.5014798|-0.7731899|-2.726919|
|               |         thumbs|228| Inf|5.424950|2.982002| 0.1582240|-0.8767117|-2.456736|
+---------------+---------------+---+----+--------+--------+----------+----------+---------+
|texting_usage_s|[-2.412,-0.304)|171| Inf|5.135798|3.153956|-0.1523407|-1.4687380|-4.436752|
|               |[-0.304, 0.325)|171| Inf|5.135798|2.778819| 0.5139458|-0.8556661|-2.677279|
|               |[ 0.325, 0.768)|180| Inf|5.187386|2.944439| 0.6931472|-0.4754237|-2.397895|
|               |[ 0.768, 1.064]|162| Inf|     Inf|4.382027| 0.4780358|-0.6931472|-2.143520|
+---------------+---------------+---+----+--------+--------+----------+----------+---------+
|         1 | id|           TRUE|684| Inf|5.424950|3.153956| 0.3787320|-0.8417346|-2.653242|
+---------------+---------------+---+----+--------+--------+----------+----------+---------+
|        Overall|               |684| Inf|5.424950|3.153956| 0.3787320|-0.8417346|-2.653242|
+---------------+---------------+---+----+--------+--------+----------+----------+---------+
plot(
  sc_sf,
  which = 1:6,
  pch = 1:6,
  xlab = 'logit',
  main = 'Harrell Plot',
  xlim = range(-3.5, 6.5)
) # no issues

Post-hoc comparisons

# Calculate the predicted values
sc_emm <- emmeans(sender_competence_int, ~ emoji_color * profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(sc_emm, by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral 0.1953186 0.1833552 0.95 -0.1640510 0.5546882 1.0652471 Inf 0.4040804
dark effect neutral 0.2285091 0.1915156 0.95 -0.1468545 0.6038728 1.1931620 Inf 0.4040804
light effect neutral -0.4238277 0.1957922 0.95 -0.8075735 -0.0400820 -2.1646810 Inf 0.0912364
yellow effect black -0.2105948 0.1915608 0.95 -0.5860471 0.1648574 -1.0993630 Inf 0.4040804
dark effect black -0.4002787 0.1817149 0.95 -0.7564333 -0.0441241 -2.2027844 Inf 0.0912364
light effect black 0.6108735 0.1908221 0.95 0.2368690 0.9848780 3.2012717 Inf 0.0123140
yellow effect white 0.1828802 0.1817404 0.95 -0.1733244 0.5390848 1.0062719 Inf 0.4040804
dark effect white -0.0448748 0.1821215 0.95 -0.4018265 0.3120768 -0.2464005 Inf 0.8053722
light effect white -0.1380054 0.1784401 0.95 -0.4877416 0.2117309 -0.7733988 Inf 0.4941972
model_parameters(
  emmeans::contrast(sc_emm, by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral effect yellow 0.0756916 0.1847731 0.95 -0.2864569 0.4378401 0.4096464 Inf 0.6836902
black effect yellow -0.2502193 0.1854775 0.95 -0.6137485 0.1133098 -1.3490551 Inf 0.3584203
white effect yellow 0.1745277 0.1832139 0.95 -0.1845649 0.5336203 0.9525900 Inf 0.5111967
neutral effect dark 0.2369650 0.1845441 0.95 -0.1247348 0.5986648 1.2840560 Inf 0.3584203
black effect dark -0.3118204 0.1835546 0.95 -0.6715808 0.0479400 -1.6987881 Inf 0.2680774
white effect dark 0.0748554 0.1837246 0.95 -0.2852382 0.4349490 0.4074327 Inf 0.6836902
neutral effect light -0.5039335 0.1872992 0.95 -0.8710333 -0.1368338 -2.6905262 Inf 0.0321027
black effect light 0.6107702 0.1840449 0.95 0.2500489 0.9714916 3.3185940 Inf 0.0081425
white effect light -0.1068367 0.1822890 0.95 -0.4641167 0.2504432 -0.5860843 Inf 0.6836902
model_parameters(
  emmeans::contrast(sc_emm, interaction = TRUE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
emoji_color_eff profile_pic_eff Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral effect 0.1394506 0.1510170 0.95 -0.1565373 0.4354385 0.9234099 Inf 0.4461288
dark effect neutral effect 0.3007239 0.1542486 0.95 -0.0015977 0.6030456 1.9496057 Inf 0.1152520
light effect neutral effect -0.4401745 0.1545912 0.95 -0.7431677 -0.1371814 -2.8473455 Inf 0.0198385
yellow effect black effect -0.2664628 0.1545356 0.95 -0.5693470 0.0364213 -1.7242814 Inf 0.1523827
dark effect black effect -0.3280639 0.1499653 0.95 -0.6219904 -0.0341373 -2.1875990 Inf 0.0860965
light effect black effect 0.5945267 0.1524491 0.95 0.2957320 0.8933214 3.8998382 Inf 0.0008663
yellow effect white effect 0.1270122 0.1498170 0.95 -0.1666236 0.4206481 0.8477828 Inf 0.4461288
dark effect white effect 0.0273399 0.1500395 0.95 -0.2667321 0.3214120 0.1822183 Inf 0.8554114
light effect white effect -0.1543522 0.1516903 0.95 -0.4516597 0.1429553 -1.0175482 Inf 0.4461288
model_parameters(
  emmeans::contrast(sc_emm, "pairwise", by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral - black yellow 0.3259109 0.3217431 0.95 -0.3046939 0.9565158 1.0129539 Inf 0.3999628
neutral - white yellow -0.0988361 0.3178284 0.95 -0.7217683 0.5240962 -0.3109730 Inf 0.7558211
black - white yellow -0.4247470 0.3190569 0.95 -1.0500871 0.2005931 -1.3312577 Inf 0.3350140
neutral - black dark 0.5487853 0.3189716 0.95 -0.0763876 1.1739583 1.7204831 Inf 0.2560340
neutral - white dark 0.1621096 0.3192651 0.95 -0.4636385 0.7878577 0.5077585 Inf 0.6880756
black - white dark -0.3866758 0.3175492 0.95 -1.0090608 0.2357092 -1.2176877 Inf 0.3350140
neutral - black light -1.1147038 0.3235394 0.95 -1.7488293 -0.4805782 -3.4453415 Inf 0.0051330
neutral - white light -0.3970968 0.3205434 0.95 -1.0253503 0.2311568 -1.2388237 Inf 0.3350140
black - white light 0.7176070 0.3148375 0.95 0.1005369 1.3346771 2.2792936 Inf 0.1019233
model_parameters(
  emmeans::contrast(sc_emm, "pairwise", by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow - dark neutral -0.0331906 0.3197813 0.95 -0.6599505 0.5935694 -0.1037914 Inf 0.9173349
yellow - light neutral 0.6191463 0.3274587 0.95 -0.0226610 1.2609537 1.8907614 Inf 0.1319765
dark - light neutral 0.6523369 0.3411840 0.95 -0.0163715 1.3210452 1.9119797 Inf 0.1319765
yellow - dark black 0.1896838 0.3209651 0.95 -0.4393961 0.8187638 0.5909797 Inf 0.7129723
yellow - light black -0.8214684 0.3364476 0.95 -1.4808934 -0.1620433 -2.4415941 Inf 0.0658016
dark - light black -1.0111522 0.3196423 0.95 -1.6376397 -0.3846647 -3.1633862 Inf 0.0140351
yellow - dark white 0.2277551 0.3171037 0.95 -0.3937567 0.8492669 0.7182354 Inf 0.7089183
yellow - light white 0.3208856 0.3107614 0.95 -0.2881955 0.9299668 1.0325788 Inf 0.5432419
dark - light white 0.0931305 0.3114301 0.95 -0.5172612 0.7035223 0.2990416 Inf 0.8605219
model_parameters(
  emmeans::contrast(sc_emm, "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow neutral - dark neutral -0.0331906 0.3197813 0.95 -0.6599505 0.5935694 -0.1037914 Inf 0.9173349
yellow neutral - light neutral 0.6191463 0.3274587 0.95 -0.0226610 1.2609537 1.8907614 Inf 0.2346248
yellow neutral - yellow black 0.3259109 0.3217431 0.95 -0.3046939 0.9565158 1.0129539 Inf 0.5332837
yellow neutral - dark black 0.5155948 0.3188825 0.95 -0.1094034 1.1405929 1.6168802 Inf 0.3465954
yellow neutral - light black -0.4955574 0.3199200 0.95 -1.1225892 0.1314743 -1.5490040 Inf 0.3641423
yellow neutral - yellow white -0.0988361 0.3178284 0.95 -0.7217683 0.5240962 -0.3109730 Inf 0.8099029
yellow neutral - dark white 0.1289190 0.3188637 0.95 -0.4960424 0.7538804 0.4043075 Inf 0.8099029
yellow neutral - light white 0.2220496 0.3122907 0.95 -0.3900290 0.8341281 0.7110347 Inf 0.6605484
dark neutral - light neutral 0.6523369 0.3411840 0.95 -0.0163715 1.3210452 1.9119797 Inf 0.2346248
dark neutral - yellow black 0.3591015 0.3133020 0.95 -0.2549591 0.9731620 1.1461834 Inf 0.4769418
dark neutral - dark black 0.5487853 0.3189716 0.95 -0.0763876 1.1739583 1.7204831 Inf 0.3072408
dark neutral - light black -0.4623669 0.3288083 0.95 -1.1068192 0.1820855 -1.4061899 Inf 0.4105742
dark neutral - yellow white -0.0656455 0.3180890 0.95 -0.6890885 0.5577975 -0.2063747 Inf 0.8603982
dark neutral - dark white 0.1621096 0.3192651 0.95 -0.4636385 0.7878577 0.5077585 Inf 0.7592558
dark neutral - light white 0.2552401 0.3116137 0.95 -0.3555115 0.8659917 0.8190915 Inf 0.6191013
light neutral - yellow black -0.2932354 0.3345598 0.95 -0.9489606 0.3624898 -0.8764812 Inf 0.5959854
light neutral - dark black -0.1035516 0.3243013 0.95 -0.7391703 0.5320672 -0.3193067 Inf 0.8099029
light neutral - light black -1.1147038 0.3235394 0.95 -1.7488293 -0.4805782 -3.4453415 Inf 0.0205322
light neutral - yellow white -0.7179824 0.3252139 0.95 -1.3553900 -0.0805748 -2.2077232 Inf 0.1962977
light neutral - dark white -0.4902273 0.3258847 0.95 -1.1289496 0.1484950 -1.5042967 Inf 0.3669369
light neutral - light white -0.3970968 0.3205434 0.95 -1.0253503 0.2311568 -1.2388237 Inf 0.4466853
yellow black - dark black 0.1896838 0.3209651 0.95 -0.4393961 0.8187638 0.5909797 Inf 0.7129723
yellow black - light black -0.8214684 0.3364476 0.95 -1.4808934 -0.1620433 -2.4415941 Inf 0.1754709
yellow black - yellow white -0.4247470 0.3190569 0.95 -1.0500871 0.2005931 -1.3312577 Inf 0.4394502
yellow black - dark white -0.1969919 0.3198311 0.95 -0.8238494 0.4298656 -0.6159248 Inf 0.7129723
yellow black - light white -0.1038614 0.3133326 0.95 -0.7179820 0.5102592 -0.3314733 Inf 0.8099029
dark black - light black -1.0111522 0.3196423 0.95 -1.6376397 -0.3846647 -3.1633862 Inf 0.0280702
dark black - yellow white -0.6144308 0.3168681 0.95 -1.2354808 0.0066191 -1.9390747 Inf 0.2346248
dark black - dark white -0.3866758 0.3175492 0.95 -1.0090608 0.2357092 -1.2176877 Inf 0.4466853
dark black - light white -0.2935452 0.3103630 0.95 -0.9018455 0.3147551 -0.9458126 Inf 0.5633087
light black - yellow white 0.3967214 0.3190979 0.95 -0.2286991 1.0221418 1.2432590 Inf 0.4466853
light black - dark white 0.6244764 0.3209598 0.95 -0.0045932 1.2535461 1.9456531 Inf 0.2346248
light black - light white 0.7176070 0.3148375 0.95 0.1005369 1.3346771 2.2792936 Inf 0.1962977
yellow white - dark white 0.2277551 0.3171037 0.95 -0.3937567 0.8492669 0.7182354 Inf 0.6605484
yellow white - light white 0.3208856 0.3107614 0.95 -0.2881955 0.9299668 1.0325788 Inf 0.5332837
dark white - light white 0.0931305 0.3114301 0.95 -0.5172612 0.7035223 0.2990416 Inf 0.8099029

Plot

# Estimated means plot

# Generate interaction-style plot for estimated marginal means
sc_plot <- emmip(sender_competence_int, ~ emoji_color * profile_pic, CIs = TRUE, mode = "mean.class")
sc_df_p <- sc_plot$data

sc_df_p <- sc_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color),
         profile_pic = str_to_title(profile_pic))

sc_df_p$profile_pic <- factor(sc_df_p$profile_pic, levels = c("Neutral",
                                                              "Black",
                                                              "White"))
# Run plot
sender_competence_pploto <-
  ggplot(sc_df_p, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(sc_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Profile Picture\n", y = "Estimated Competence Ratings\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
     limits = c(3.4, 4.5),
     breaks = seq(3.4, 4.5, 0.2),
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip()
sender_competence_pploto

# Save plot
# ggsave(filename = "sender_competence_pplot.svg", width = 216, height = 131, unit = "mm", dpi = 300)
rm(list = ls(pattern = "^sc_"), anova_model, residuals_anova, dfp_clean, original_range, estimated_range, scaling_factor)

Senders Competence compared with Warmth (not scaled)

dfp_m <-
  dfp %>% dplyr::select(
    sender_competence,
    sender_warmth,
    emoji_color,
    profile_pic,
    emoji_hand_type,
    texting_usage_s,
    id
  ) %>% pivot_longer(
    cols = c(sender_competence, sender_warmth),
    names_to = "measures",
    values_to = "response"
  ) %>% mutate(response = as.factor(response))

merge <-
  clmm(
    response ~ 1 + measures * emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp_m,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

RVAideMemoire::Anova.clmm(merge, type = "3")
Analysis of Deviance Table (Type III tests)

Response: response
                                 LR Chisq Df  Pr(>Chisq)    
measures                           0.0000  1   1.0000000    
emoji_color                        0.0000  2   1.0000000    
profile_pic                        0.0000  2   1.0000000    
emoji_hand_type                   15.7601  2   0.0003782 ***
texting_usage_s                    5.4351  1   0.0197360 *  
measures:emoji_color               0.0000  2   1.0000000    
measures:profile_pic               0.0000  2   1.0000000    
emoji_color:profile_pic            0.0000  4   1.0000000    
measures:emoji_color:profile_pic  31.5209  4 0.000002397 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
emmip(merge, measures ~ emoji_color | profile_pic, type = "response") + coord_flip() + theme_test()

sc_m <- emmeans(merge, ~ measures * emoji_color * profile_pic)

model_parameters(
  emmeans::contrast(sc_m, "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
sender_competence yellow neutral - sender_warmth yellow neutral 0.4910799 0.3166771 0.95 -0.1295958 1.1117555 1.5507276 Inf 0.3552203
sender_competence yellow neutral - sender_competence dark neutral 0.2249957 0.3057624 0.95 -0.3742876 0.8242791 0.7358515 Inf 0.7065863
sender_competence yellow neutral - sender_warmth dark neutral -0.0173093 0.3114526 0.95 -0.6277451 0.5931265 -0.0555761 Inf 0.9813353
sender_competence yellow neutral - sender_competence light neutral 0.3107041 0.3073123 0.95 -0.2916168 0.9130251 1.0110372 Inf 0.6042505
sender_competence yellow neutral - sender_warmth light neutral -0.2952743 0.3066510 0.95 -0.8962992 0.3057506 -0.9629002 Inf 0.6137110
sender_competence yellow neutral - sender_competence yellow black 0.4893753 0.3082361 0.95 -0.1147564 1.0935070 1.5876637 Inf 0.3508459
sender_competence yellow neutral - sender_warmth yellow black -0.0259257 0.3066282 0.95 -0.6269060 0.5750546 -0.0845509 Inf 0.9681324
sender_competence yellow neutral - sender_competence dark black 0.4046173 0.3035837 0.95 -0.1903958 0.9996305 1.3328031 Inf 0.4365196
sender_competence yellow neutral - sender_warmth dark black -0.4896086 0.3046775 0.95 -1.0867654 0.1075483 -1.6069734 Inf 0.3508459
sender_competence yellow neutral - sender_competence light black -0.6008428 0.3046485 0.95 -1.1979430 -0.0037427 -1.9722492 Inf 0.2397716
sender_competence yellow neutral - sender_warmth light black 0.5987108 0.3102598 0.95 -0.0093872 1.2068088 1.9297082 Inf 0.2487085
sender_competence yellow neutral - sender_competence yellow white -0.0800043 0.3070854 0.95 -0.6818806 0.5218719 -0.2605280 Inf 0.8919301
sender_competence yellow neutral - sender_warmth yellow white 0.1516988 0.3138651 0.95 -0.4634656 0.7668631 0.4833247 Inf 0.7950652
sender_competence yellow neutral - sender_competence dark white 0.1383190 0.3056374 0.95 -0.4607192 0.7373573 0.4525592 Inf 0.8030849
sender_competence yellow neutral - sender_warmth dark white 0.4560467 0.3047060 0.95 -0.1411660 1.0532594 1.4966779 Inf 0.3674106
sender_competence yellow neutral - sender_competence light white 0.2012844 0.3012890 0.95 -0.3892311 0.7917999 0.6680776 Inf 0.7275930
sender_competence yellow neutral - sender_warmth light white 0.1266537 0.3003028 0.95 -0.4619290 0.7152365 0.4217533 Inf 0.8240030
sender_warmth yellow neutral - sender_competence dark neutral -0.2660841 0.3129483 0.95 -0.8794516 0.3472833 -0.8502495 Inf 0.6501454
sender_warmth yellow neutral - sender_warmth dark neutral -0.5083892 0.3185248 0.95 -1.1326863 0.1159079 -1.5960741 Inf 0.3508459
sender_warmth yellow neutral - sender_competence light neutral -0.1803757 0.3157173 0.95 -0.7991703 0.4384189 -0.5713204 Inf 0.7656463
sender_warmth yellow neutral - sender_warmth light neutral -0.7863542 0.3160471 0.95 -1.4057951 -0.1669133 -2.4880919 Inf 0.1105891
sender_warmth yellow neutral - sender_competence yellow black -0.0017046 0.3149020 0.95 -0.6189011 0.6154919 -0.0054131 Inf 0.9956810
sender_warmth yellow neutral - sender_warmth yellow black -0.5170056 0.3135684 0.95 -1.1315884 0.0975773 -1.6487806 Inf 0.3454020
sender_warmth yellow neutral - sender_competence dark black -0.0864626 0.3113570 0.95 -0.6967111 0.5237859 -0.2776959 Inf 0.8872917
sender_warmth yellow neutral - sender_warmth dark black -0.9806884 0.3131359 0.95 -1.5944236 -0.3669533 -3.1318299 Inf 0.0295325
sender_warmth yellow neutral - sender_competence light black -1.0919227 0.3142874 0.95 -1.7079147 -0.4759307 -3.4742806 Inf 0.0156741
sender_warmth yellow neutral - sender_warmth light black 0.1076309 0.3183285 0.95 -0.5162814 0.7315433 0.3381128 Inf 0.8711179
sender_warmth yellow neutral - sender_competence yellow white -0.5710842 0.3151257 0.95 -1.1887191 0.0465507 -1.8122429 Inf 0.2892472
sender_warmth yellow neutral - sender_warmth yellow white -0.3393811 0.3215880 0.95 -0.9696821 0.2909199 -1.0553287 Inf 0.5878623
sender_warmth yellow neutral - sender_competence dark white -0.3527609 0.3139155 0.95 -0.9680239 0.2625022 -1.1237448 Inf 0.5626981
sender_warmth yellow neutral - sender_warmth dark white -0.0350332 0.3123525 0.95 -0.6472328 0.5771665 -0.1121591 Inf 0.9629216
sender_warmth yellow neutral - sender_competence light white -0.2897955 0.3094177 0.95 -0.8962430 0.3166521 -0.9365834 Inf 0.6137110
sender_warmth yellow neutral - sender_warmth light white -0.3644262 0.3082974 0.95 -0.9686779 0.2398256 -1.1820606 Inf 0.5259245
sender_competence dark neutral - sender_warmth dark neutral -0.2423051 0.3012009 0.95 -0.8326480 0.3480379 -0.8044632 Inf 0.6711752
sender_competence dark neutral - sender_competence light neutral 0.0857084 0.3110606 0.95 -0.5239591 0.6953759 0.2755361 Inf 0.8872917
sender_competence dark neutral - sender_warmth light neutral -0.5202700 0.3110020 0.95 -1.1298227 0.0892826 -1.6728834 Inf 0.3454020
sender_competence dark neutral - sender_competence yellow black 0.2643795 0.3002187 0.95 -0.3240384 0.8527975 0.8806231 Inf 0.6419329
sender_competence dark neutral - sender_warmth yellow black -0.2509214 0.2979134 0.95 -0.8348210 0.3329782 -0.8422629 Inf 0.6504792
sender_competence dark neutral - sender_competence dark black 0.1796216 0.3003735 0.95 -0.4090996 0.7683427 0.5979942 Inf 0.7647828
sender_competence dark neutral - sender_warmth dark black -0.7146043 0.3017866 0.95 -1.3060952 -0.1231134 -2.3679124 Inf 0.1244083
sender_competence dark neutral - sender_competence light black -0.8258386 0.3065172 0.95 -1.4266012 -0.2250759 -2.6942652 Inf 0.0781535
sender_competence dark neutral - sender_warmth light black 0.3737151 0.3109424 0.95 -0.2357209 0.9831510 1.2018787 Inf 0.5161737
sender_competence dark neutral - sender_competence yellow white -0.3050001 0.3042568 0.95 -0.9013325 0.2913324 -1.0024427 Inf 0.6045983
sender_competence dark neutral - sender_warmth yellow white -0.0732970 0.3111604 0.95 -0.6831602 0.5365663 -0.2355600 Inf 0.9022278
sender_competence dark neutral - sender_competence dark white -0.0866767 0.3027365 0.95 -0.6800294 0.5066760 -0.2863107 Inf 0.8872917
sender_competence dark neutral - sender_warmth dark white 0.2310510 0.3009146 0.95 -0.3587308 0.8208327 0.7678291 Inf 0.6968903
sender_competence dark neutral - sender_competence light white -0.0237113 0.2975929 0.95 -0.6069826 0.5595600 -0.0796771 Inf 0.9681324
sender_competence dark neutral - sender_warmth light white -0.0983420 0.2965377 0.95 -0.6795451 0.4828611 -0.3316342 Inf 0.8711179
sender_warmth dark neutral - sender_competence light neutral 0.3280135 0.3166622 0.95 -0.2926331 0.9486600 1.0358466 Inf 0.5966478
sender_warmth dark neutral - sender_warmth light neutral -0.2779650 0.3158735 0.95 -0.8970657 0.3411357 -0.8799883 Inf 0.6419329
sender_warmth dark neutral - sender_competence yellow black 0.5066846 0.3074348 0.95 -0.0958765 1.1092457 1.6481042 Inf 0.3454020
sender_warmth dark neutral - sender_warmth yellow black -0.0086164 0.3048584 0.95 -0.6061278 0.5888951 -0.0282635 Inf 0.9838826
sender_warmth dark neutral - sender_competence dark black 0.4219266 0.3062126 0.95 -0.1782391 1.0220923 1.3778878 Inf 0.4151678
sender_warmth dark neutral - sender_warmth dark black -0.4722993 0.3075133 0.95 -1.0750143 0.1304158 -1.5358660 Inf 0.3552203
sender_warmth dark neutral - sender_competence light black -0.5835335 0.3108067 0.95 -1.1927035 0.0256365 -1.8774803 Inf 0.2682529
sender_warmth dark neutral - sender_warmth light black 0.6160201 0.3158351 0.95 -0.0030053 1.2350456 1.9504486 Inf 0.2444303
sender_warmth dark neutral - sender_competence yellow white -0.0626950 0.3100107 0.95 -0.6703047 0.5449147 -0.2022350 Inf 0.9177082
sender_warmth dark neutral - sender_warmth yellow white 0.1690081 0.3166015 0.95 -0.4515195 0.7895357 0.5338196 Inf 0.7827617
sender_warmth dark neutral - sender_competence dark white 0.1556283 0.3088769 0.95 -0.4497592 0.7610159 0.5038524 Inf 0.7898980
sender_warmth dark neutral - sender_warmth dark white 0.4733560 0.3070333 0.95 -0.1284183 1.0751303 1.5417089 Inf 0.3552203
sender_warmth dark neutral - sender_competence light white 0.2185937 0.3038376 0.95 -0.3769170 0.8141044 0.7194427 Inf 0.7090439
sender_warmth dark neutral - sender_warmth light white 0.1439630 0.3023534 0.95 -0.4486388 0.7365649 0.4761416 Inf 0.7950652
sender_competence light neutral - sender_warmth light neutral -0.6059785 0.2992748 0.95 -1.1925463 -0.0194106 -2.0248229 Inf 0.2262582
sender_competence light neutral - sender_competence yellow black 0.1786711 0.3098397 0.95 -0.4286036 0.7859459 0.5766566 Inf 0.7656463
sender_competence light neutral - sender_warmth yellow black -0.3366298 0.3088264 0.95 -0.9419184 0.2686588 -1.0900294 Inf 0.5778374
sender_competence light neutral - sender_competence dark black 0.0939132 0.3016556 0.95 -0.4973209 0.6851472 0.3113258 Inf 0.8824397
sender_competence light neutral - sender_warmth dark black -0.8003127 0.3036085 0.95 -1.3953744 -0.2052510 -2.6360026 Inf 0.0855669
sender_competence light neutral - sender_competence light black -0.9115470 0.3009166 0.95 -1.5013326 -0.3217613 -3.0292350 Inf 0.0375116
sender_competence light neutral - sender_warmth light black 0.2880067 0.3056939 0.95 -0.3111424 0.8871557 0.9421407 Inf 0.6137110
sender_competence light neutral - sender_competence yellow white -0.3907085 0.3055383 0.95 -0.9895526 0.2081356 -1.2787544 Inf 0.4659164
sender_competence light neutral - sender_warmth yellow white -0.1590054 0.3127237 0.95 -0.7719326 0.4539219 -0.5084531 Inf 0.7898980
sender_competence light neutral - sender_competence dark white -0.1723851 0.3038467 0.95 -0.7679137 0.4231434 -0.5673425 Inf 0.7656463
sender_competence light neutral - sender_warmth dark white 0.1453426 0.3033353 0.95 -0.4491838 0.7398689 0.4791481 Inf 0.7950652
sender_competence light neutral - sender_competence light white -0.1094197 0.3001877 0.95 -0.6977769 0.4789374 -0.3645044 Inf 0.8619579
sender_competence light neutral - sender_warmth light white -0.1840504 0.2993756 0.95 -0.7708157 0.4027149 -0.6147811 Inf 0.7561559
sender_warmth light neutral - sender_competence yellow black 0.7846496 0.3100328 0.95 0.1769965 1.3923027 2.5308600 Inf 0.1088053
sender_warmth light neutral - sender_warmth yellow black 0.2693486 0.3079753 0.95 -0.3342719 0.8729691 0.8745787 Inf 0.6419329
sender_warmth light neutral - sender_competence dark black 0.6998916 0.3017277 0.95 0.1085163 1.2912670 2.3196137 Inf 0.1298064
sender_warmth light neutral - sender_warmth dark black -0.1943343 0.3025311 0.95 -0.7872843 0.3986158 -0.6423612 Inf 0.7412185
sender_warmth light neutral - sender_competence light black -0.3055685 0.2994170 0.95 -0.8924151 0.2812780 -1.0205450 Inf 0.6031144
sender_warmth light neutral - sender_warmth light black 0.8939851 0.3057417 0.95 0.2947424 1.4932279 2.9239882 Inf 0.0440612
sender_warmth light neutral - sender_competence yellow white 0.2152700 0.3049403 0.95 -0.3824020 0.8129420 0.7059414 Inf 0.7133433
sender_warmth light neutral - sender_warmth yellow white 0.4469731 0.3120234 0.95 -0.1645815 1.0585277 1.4324988 Inf 0.3955722
sender_warmth light neutral - sender_competence dark white 0.4335933 0.3036160 0.95 -0.1614831 1.0286697 1.4280978 Inf 0.3955722
sender_warmth light neutral - sender_warmth dark white 0.7513210 0.3033466 0.95 0.1567725 1.3458695 2.4767738 Inf 0.1105891
sender_warmth light neutral - sender_competence light white 0.4965587 0.3000898 0.95 -0.0916064 1.0847238 1.6547007 Inf 0.3454020
sender_warmth light neutral - sender_warmth light white 0.4219280 0.2986447 0.95 -0.1634048 1.0072609 1.4128093 Inf 0.3955722
sender_competence yellow black - sender_warmth yellow black -0.5153010 0.2980399 0.95 -1.0994485 0.0688466 -1.7289662 Inf 0.3288133
sender_competence yellow black - sender_competence dark black -0.0847580 0.3029048 0.95 -0.6784404 0.5089244 -0.2798173 Inf 0.8872917
sender_competence yellow black - sender_warmth dark black -0.9789839 0.3049646 0.95 -1.5767035 -0.3812642 -3.2101554 Inf 0.0289964
sender_competence yellow black - sender_competence light black -1.0902181 0.3117314 0.95 -1.7012003 -0.4792359 -3.4973002 Inf 0.0156741
sender_competence yellow black - sender_warmth light black 0.1093355 0.3158567 0.95 -0.5097322 0.7284033 0.3461555 Inf 0.8711179
sender_competence yellow black - sender_competence yellow white -0.5693796 0.3060408 0.95 -1.1692086 0.0304494 -1.8604694 Inf 0.2682529
sender_competence yellow black - sender_warmth yellow white -0.3376765 0.3128721 0.95 -0.9508945 0.2755415 -1.0792798 Inf 0.5798763
sender_competence yellow black - sender_competence dark white -0.3510563 0.3048522 0.95 -0.9485556 0.2464431 -1.1515622 Inf 0.5453379
sender_competence yellow black - sender_warmth dark white -0.0333286 0.3035556 0.95 -0.6282867 0.5616295 -0.1097940 Inf 0.9629216
sender_competence yellow black - sender_competence light white -0.2880909 0.3001771 0.95 -0.8764271 0.3002453 -0.9597365 Inf 0.6137110
sender_competence yellow black - sender_warmth light white -0.3627216 0.2991052 0.95 -0.9489570 0.2235139 -1.2126889 Inf 0.5143741
sender_warmth yellow black - sender_competence dark black 0.4305430 0.3013056 0.95 -0.1600052 1.0210912 1.4289245 Inf 0.3955722
sender_warmth yellow black - sender_warmth dark black -0.4636829 0.3025445 0.95 -1.0566592 0.1292935 -1.5326104 Inf 0.3552203
sender_warmth yellow black - sender_competence light black -0.5749171 0.3093685 0.95 -1.1812683 0.0314340 -1.8583570 Inf 0.2682529
sender_warmth yellow black - sender_warmth light black 0.6246365 0.3146593 0.95 0.0079157 1.2413573 1.9851203 Inf 0.2397716
sender_warmth yellow black - sender_competence yellow white -0.0540786 0.3043613 0.95 -0.6506159 0.5424586 -0.1776791 Inf 0.9302578
sender_warmth yellow black - sender_warmth yellow white 0.1776245 0.3112242 0.95 -0.4323638 0.7876127 0.5707283 Inf 0.7656463
sender_warmth yellow black - sender_competence dark white 0.1642447 0.3031538 0.95 -0.4299258 0.7584152 0.5417867 Inf 0.7822496
sender_warmth yellow black - sender_warmth dark white 0.4819724 0.3017334 0.95 -0.1094143 1.0733591 1.5973449 Inf 0.3508459
sender_warmth yellow black - sender_competence light white 0.2272101 0.2983821 0.95 -0.3576080 0.8120282 0.7614737 Inf 0.6968903
sender_warmth yellow black - sender_warmth light white 0.1525794 0.2969925 0.95 -0.4295153 0.7346741 0.5137483 Inf 0.7898980
sender_competence dark black - sender_warmth dark black -0.8942259 0.2999152 0.95 -1.4820489 -0.3064029 -2.9815957 Inf 0.0398844
sender_competence dark black - sender_competence light black -1.0054601 0.2999666 0.95 -1.5933839 -0.4175364 -3.3519067 Inf 0.0204656
sender_competence dark black - sender_warmth light black 0.1940935 0.3040310 0.95 -0.4017963 0.7899833 0.6384004 Inf 0.7412185
sender_competence dark black - sender_competence yellow white -0.4846216 0.3019504 0.95 -1.0764336 0.1071903 -1.6049710 Inf 0.3508459
sender_competence dark black - sender_warmth yellow white -0.2529185 0.3088360 0.95 -0.8582261 0.3523890 -0.8189411 Inf 0.6648575
sender_competence dark black - sender_competence dark white -0.2662983 0.3003059 0.95 -0.8548870 0.3222904 -0.8867568 Inf 0.6419329
sender_competence dark black - sender_warmth dark white 0.0514294 0.2988732 0.95 -0.5343513 0.6372100 0.1720776 Inf 0.9302578
sender_competence dark black - sender_competence light white -0.2033329 0.2956720 0.95 -0.7828393 0.3761735 -0.6876976 Inf 0.7163944
sender_competence dark black - sender_warmth light white -0.2779636 0.2947141 0.95 -0.8555927 0.2996655 -0.9431634 Inf 0.6137110
sender_warmth dark black - sender_competence light black -0.1112343 0.3001133 0.95 -0.6994455 0.4769769 -0.3706409 Inf 0.8619579
sender_warmth dark black - sender_warmth light black 1.0883194 0.3064150 0.95 0.4877570 1.6888818 3.5517820 Inf 0.0156741
sender_warmth dark black - sender_competence yellow white 0.4096042 0.3031124 0.95 -0.1844852 1.0036937 1.3513278 Inf 0.4288625
sender_warmth dark black - sender_warmth yellow white 0.6413073 0.3106399 0.95 0.0324644 1.2501503 2.0644722 Inf 0.2129594
sender_warmth dark black - sender_competence dark white 0.6279276 0.3019063 0.95 0.0362022 1.2196530 2.0798759 Inf 0.2127092
sender_warmth dark black - sender_warmth dark white 0.9456553 0.3011179 0.95 0.3554751 1.5358354 3.1404822 Inf 0.0295325
sender_warmth dark black - sender_competence light white 0.6908930 0.2976762 0.95 0.1074583 1.2743276 2.3209546 Inf 0.1298064
sender_warmth dark black - sender_warmth light white 0.6162623 0.2962690 0.95 0.0355856 1.1969389 2.0800766 Inf 0.2127092
sender_competence light black - sender_warmth light black 1.1995536 0.3007266 0.95 0.6101403 1.7889670 3.9888507 Inf 0.0101583
sender_competence light black - sender_competence yellow white 0.5208385 0.3035402 0.95 -0.0740893 1.1157663 1.7158800 Inf 0.3296538
sender_competence light black - sender_warmth yellow white 0.7525416 0.3109736 0.95 0.1430445 1.3620387 2.4199531 Inf 0.1130926
sender_competence light black - sender_competence dark white 0.7391618 0.3022260 0.95 0.1468099 1.3315138 2.4457259 Inf 0.1105891
sender_competence light black - sender_warmth dark white 1.0568895 0.3017921 0.95 0.4653879 1.6483911 3.5020454 Inf 0.0156741
sender_competence light black - sender_competence light white 0.8021272 0.2982201 0.95 0.2176265 1.3866279 2.6897154 Inf 0.0781535
sender_competence light black - sender_warmth light white 0.7274965 0.2969751 0.95 0.1454360 1.3095571 2.4496884 Inf 0.1105891
sender_warmth light black - sender_competence yellow white -0.6787151 0.3087637 0.95 -1.2838809 -0.0735494 -2.1981702 Inf 0.1709743
sender_warmth light black - sender_warmth yellow white -0.4470120 0.3158343 0.95 -1.0660359 0.1720118 -1.4153372 Inf 0.3955722
sender_warmth light black - sender_competence dark white -0.4603918 0.3071088 0.95 -1.0623140 0.1415304 -1.4991162 Inf 0.3674106
sender_warmth light black - sender_warmth dark white -0.1426641 0.3058793 0.95 -0.7421766 0.4568484 -0.4664065 Inf 0.7972476
sender_warmth light black - sender_competence light white -0.3974264 0.3030003 0.95 -0.9912961 0.1964433 -1.3116368 Inf 0.4463897
sender_warmth light black - sender_warmth light white -0.4720571 0.3017899 0.95 -1.0635545 0.1194403 -1.5641910 Inf 0.3552203
sender_competence yellow white - sender_warmth yellow white 0.2317031 0.3123216 0.95 -0.3804359 0.8438421 0.7418735 Inf 0.7065863
sender_competence yellow white - sender_competence dark white 0.2183233 0.3040294 0.95 -0.3775633 0.8142100 0.7180995 Inf 0.7090439
sender_competence yellow white - sender_warmth dark white 0.5360510 0.3031370 0.95 -0.0580866 1.1301886 1.7683457 Inf 0.3100389
sender_competence yellow white - sender_competence light white 0.2812887 0.2997346 0.95 -0.3061804 0.8687579 0.9384592 Inf 0.6137110
sender_competence yellow white - sender_warmth light white 0.2066580 0.2986339 0.95 -0.3786536 0.7919696 0.6920114 Inf 0.7163944
sender_warmth yellow white - sender_competence dark white -0.0133798 0.3110482 0.95 -0.6230231 0.5962636 -0.0430151 Inf 0.9815250
sender_warmth yellow white - sender_warmth dark white 0.3043479 0.3100015 0.95 -0.3032439 0.9119398 0.9817626 Inf 0.6137110
sender_warmth yellow white - sender_competence light white 0.0495856 0.3066985 0.95 -0.5515323 0.6507036 0.1616755 Inf 0.9325097
sender_warmth yellow white - sender_warmth light white -0.0250451 0.3056494 0.95 -0.6241069 0.5740167 -0.0819405 Inf 0.9681324
sender_competence dark white - sender_warmth dark white 0.3177277 0.3015288 0.95 -0.2732580 0.9087133 1.0537224 Inf 0.5878623
sender_competence dark white - sender_competence light white 0.0629654 0.2980991 0.95 -0.5212980 0.6472288 0.2112231 Inf 0.9165836
sender_competence dark white - sender_warmth light white -0.0116653 0.2972390 0.95 -0.5942430 0.5709124 -0.0392455 Inf 0.9815250
sender_warmth dark white - sender_competence light white -0.2547623 0.2967566 0.95 -0.8363945 0.3268699 -0.8584891 Inf 0.6496221
sender_warmth dark white - sender_warmth light white -0.3293930 0.2958137 0.95 -0.9091771 0.2503911 -1.1135151 Inf 0.5641604
sender_competence light white - sender_warmth light white -0.0746307 0.2925702 0.95 -0.6480578 0.4987964 -0.2550865 Inf 0.8919301
model_parameters(
  emmeans::contrast(sc_m,"pairwise", by = c("emoji_color", "profile_pic")),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
)
contrast                          | emoji_color | profile_pic | Coefficient |   SE |         95% CI |     z |      p
--------------------------------------------------------------------------------------------------------------------
sender_competence - sender_warmth |      yellow |     neutral |        0.49 | 0.32 | [-0.13,  1.11] |  1.55 | 0.218 
sender_competence - sender_warmth |        dark |     neutral |       -0.24 | 0.30 | [-0.83,  0.35] | -0.80 | 0.515 
sender_competence - sender_warmth |       light |     neutral |       -0.61 | 0.30 | [-1.19, -0.02] | -2.02 | 0.129 
sender_competence - sender_warmth |      yellow |       black |       -0.52 | 0.30 | [-1.10,  0.07] | -1.73 | 0.189 
sender_competence - sender_warmth |        dark |       black |       -0.89 | 0.30 | [-1.48, -0.31] | -2.98 | 0.013 
sender_competence - sender_warmth |       light |       black |        1.20 | 0.30 | [ 0.61,  1.79] |  3.99 | < .001
sender_competence - sender_warmth |      yellow |       white |        0.23 | 0.31 | [-0.38,  0.84] |  0.74 | 0.515 
sender_competence - sender_warmth |        dark |       white |        0.32 | 0.30 | [-0.27,  0.91] |  1.05 | 0.438 
sender_competence - sender_warmth |       light |       white |       -0.07 | 0.29 | [-0.65,  0.50] | -0.26 | 0.799 

p-value adjustment method: Benjamini & Hochberg (1995)
model_parameters(
  emmeans::contrast(sc_m, by = c("emoji_color", "profile_pic")),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
)
contrast                 | emoji_color | profile_pic | Coefficient |   SE |         95% CI |     z |      p
-----------------------------------------------------------------------------------------------------------
sender_competence effect |      yellow |     neutral |        0.25 | 0.16 | [-0.06,  0.56] |  1.55 | 0.218 
sender_warmth effect     |      yellow |     neutral |       -0.25 | 0.16 | [-0.56,  0.06] | -1.55 | 0.218 
sender_competence effect |        dark |     neutral |       -0.12 | 0.15 | [-0.42,  0.17] | -0.80 | 0.515 
sender_warmth effect     |        dark |     neutral |        0.12 | 0.15 | [-0.17,  0.42] |  0.80 | 0.515 
sender_competence effect |       light |     neutral |       -0.30 | 0.15 | [-0.60, -0.01] | -2.02 | 0.129 
sender_warmth effect     |       light |     neutral |        0.30 | 0.15 | [ 0.01,  0.60] |  2.02 | 0.129 
sender_competence effect |      yellow |       black |       -0.26 | 0.15 | [-0.55,  0.03] | -1.73 | 0.189 
sender_warmth effect     |      yellow |       black |        0.26 | 0.15 | [-0.03,  0.55] |  1.73 | 0.189 
sender_competence effect |        dark |       black |       -0.45 | 0.15 | [-0.74, -0.15] | -2.98 | 0.013 
sender_warmth effect     |        dark |       black |        0.45 | 0.15 | [ 0.15,  0.74] |  2.98 | 0.013 
sender_competence effect |       light |       black |        0.60 | 0.15 | [ 0.31,  0.89] |  3.99 | < .001
sender_warmth effect     |       light |       black |       -0.60 | 0.15 | [-0.89, -0.31] | -3.99 | < .001
sender_competence effect |      yellow |       white |        0.12 | 0.16 | [-0.19,  0.42] |  0.74 | 0.515 
sender_warmth effect     |      yellow |       white |       -0.12 | 0.16 | [-0.42,  0.19] | -0.74 | 0.515 
sender_competence effect |        dark |       white |        0.16 | 0.15 | [-0.14,  0.45] |  1.05 | 0.438 
sender_warmth effect     |        dark |       white |       -0.16 | 0.15 | [-0.45,  0.14] | -1.05 | 0.438 
sender_competence effect |       light |       white |       -0.04 | 0.15 | [-0.32,  0.25] | -0.26 | 0.799 
sender_warmth effect     |       light |       white |        0.04 | 0.15 | [-0.25,  0.32] |  0.26 | 0.799 

p-value adjustment method: Benjamini & Hochberg (1995)

Senders Competence compared with Warmth (scaled)

dfp_m <-
  dfp %>% dplyr::select(
    sender_competence,
    sender_warmth,
    emoji_color,
    profile_pic,
    emoji_hand_type,
    texting_usage_s,
    id
  ) %>% pivot_longer(
    cols = c(sender_competence, sender_warmth),
    names_to = "measures",
    values_to = "response"
  )

dfp_m$response <- scale(dfp_m$response)

merge <-
  lmer(
    response ~ 1 + measures * emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp_m
  )

Anova(merge, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: response
                                   Chisq Df  Pr(>Chisq)    
(Intercept)                       0.3641  1    0.546250    
measures                          2.5709  1    0.108842    
emoji_color                       0.1446  2    0.930245    
profile_pic                       4.9067  2    0.086003 .  
emoji_hand_type                  19.8758  2 0.000048310 ***
texting_usage_s                   5.7253  1    0.016722 *  
measures:emoji_color              5.1578  2    0.075859 .  
measures:profile_pic              6.3956  2    0.040851 *  
emoji_color:profile_pic          13.5884  4    0.008732 ** 
measures:emoji_color:profile_pic 32.1615  4 0.000001773 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
emmip(merge, measures ~ emoji_color | profile_pic, type = "response") + coord_flip() + theme_test()

sc_m <- emmeans(merge, ~ measures * emoji_color * profile_pic)

model_parameters(
  emmeans::contrast(sc_m, "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high t df_error p
sender_competence yellow neutral - sender_warmth yellow neutral 0.2232242 0.1392178 0.95 -0.0498973 0.4963457 1.6034177 1273 0.3272716
sender_competence yellow neutral - sender_competence dark neutral 0.0509047 0.1406949 0.95 -0.2251147 0.3269241 0.3618092 1273 0.8782869
sender_competence yellow neutral - sender_warmth dark neutral -0.0359047 0.1406949 0.95 -0.3119241 0.2401147 -0.2551955 1273 0.8918820
sender_competence yellow neutral - sender_competence light neutral 0.0383699 0.1409613 0.95 -0.2381721 0.3149119 0.2722015 1273 0.8838813
sender_competence yellow neutral - sender_warmth light neutral -0.1724530 0.1409613 0.95 -0.4489950 0.1040890 -1.2234066 1273 0.4457183
sender_competence yellow neutral - sender_competence yellow black 0.1804800 0.1406488 0.95 -0.0954488 0.4564088 1.2831966 1273 0.4457183
sender_competence yellow neutral - sender_warmth yellow black -0.0551456 0.1406488 0.95 -0.3310744 0.2207833 -0.3920799 1273 0.8576203
sender_competence yellow neutral - sender_competence dark black 0.1138548 0.1392402 0.95 -0.1593108 0.3870203 0.8176861 1273 0.6562354
sender_competence yellow neutral - sender_warmth dark black -0.2705869 0.1392402 0.95 -0.5437524 0.0025787 -1.9433098 1273 0.2101693
sender_competence yellow neutral - sender_competence light black -0.3396773 0.1410871 0.95 -0.6164660 -0.0628886 -2.4075722 1273 0.1126673
sender_competence yellow neutral - sender_warmth light black 0.2679886 0.1410871 0.95 -0.0088001 0.5447773 1.8994559 1273 0.2264808
sender_competence yellow neutral - sender_competence yellow white -0.1303409 0.1392277 0.95 -0.4034819 0.1428000 -0.9361711 1273 0.5747579
sender_competence yellow neutral - sender_warmth yellow white 0.0308765 0.1392277 0.95 -0.2422644 0.3040175 0.2217702 1273 0.8947010
sender_competence yellow neutral - sender_competence dark white -0.0317976 0.1392343 0.95 -0.3049515 0.2413563 -0.2283747 1273 0.8947010
sender_competence yellow neutral - sender_warmth dark white 0.1790253 0.1392343 0.95 -0.0941287 0.4521792 1.2857841 1273 0.4457183
sender_competence yellow neutral - sender_competence light white 0.0060739 0.1392277 0.95 -0.2670671 0.2792148 0.0436253 1273 0.9845141
sender_competence yellow neutral - sender_warmth light white 0.0060739 0.1392277 0.95 -0.2670671 0.2792148 0.0436253 1273 0.9845141
sender_warmth yellow neutral - sender_competence dark neutral -0.1723195 0.1406949 0.95 -0.4483389 0.1036999 -1.2247743 1273 0.4457183
sender_warmth yellow neutral - sender_warmth dark neutral -0.2591289 0.1406949 0.95 -0.5351483 0.0168905 -1.8417790 1273 0.2392648
sender_warmth yellow neutral - sender_competence light neutral -0.1848543 0.1409613 0.95 -0.4613963 0.0916877 -1.3113836 1273 0.4457183
sender_warmth yellow neutral - sender_warmth light neutral -0.3956772 0.1409613 0.95 -0.6722192 -0.1191352 -2.8069917 1273 0.0647307
sender_warmth yellow neutral - sender_competence yellow black -0.0427442 0.1406488 0.95 -0.3186731 0.2331846 -0.3039075 1273 0.8810455
sender_warmth yellow neutral - sender_warmth yellow black -0.2783698 0.1406488 0.95 -0.5542986 -0.0024409 -1.9791840 1273 0.2040445
sender_warmth yellow neutral - sender_competence dark black -0.1093694 0.1392402 0.95 -0.3825350 0.1637961 -0.7854728 1273 0.6716910
sender_warmth yellow neutral - sender_warmth dark black -0.4938111 0.1392402 0.95 -0.7669767 -0.2206456 -3.5464687 1273 0.0103174
sender_warmth yellow neutral - sender_competence light black -0.5629015 0.1410871 0.95 -0.8396902 -0.2861128 -3.9897459 1273 0.0053484
sender_warmth yellow neutral - sender_warmth light black 0.0447644 0.1410871 0.95 -0.2320243 0.3215531 0.3172823 1273 0.8810455
sender_warmth yellow neutral - sender_competence yellow white -0.3535651 0.1392277 0.95 -0.6267061 -0.0804242 -2.5394744 1273 0.1009806
sender_warmth yellow neutral - sender_warmth yellow white -0.1923477 0.1392277 0.95 -0.4654886 0.0807933 -1.3815331 1273 0.4000891
sender_warmth yellow neutral - sender_competence dark white -0.2550218 0.1392343 0.95 -0.5281758 0.0181321 -1.8316018 1273 0.2392648
sender_warmth yellow neutral - sender_warmth dark white -0.0441989 0.1392343 0.95 -0.3173529 0.2289550 -0.3174429 1273 0.8810455
sender_warmth yellow neutral - sender_competence light white -0.2171504 0.1392277 0.95 -0.4902913 0.0559906 -1.5596779 1273 0.3321978
sender_warmth yellow neutral - sender_warmth light white -0.2171504 0.1392277 0.95 -0.4902913 0.0559906 -1.5596779 1273 0.3321978
sender_competence dark neutral - sender_warmth dark neutral -0.0868094 0.1392178 0.95 -0.3599309 0.1863120 -0.6235513 1273 0.7621888
sender_competence dark neutral - sender_competence light neutral -0.0125348 0.1455352 0.95 -0.2980501 0.2729805 -0.0861292 1273 0.9693927
sender_competence dark neutral - sender_warmth light neutral -0.2233577 0.1455352 0.95 -0.5088730 0.0621576 -1.5347327 1273 0.3321978
sender_competence dark neutral - sender_competence yellow black 0.1295753 0.1405744 0.95 -0.1462076 0.4053582 0.9217562 1273 0.5807984
sender_competence dark neutral - sender_warmth yellow black -0.1060503 0.1405744 0.95 -0.3818332 0.1697327 -0.7544068 1273 0.6828110
sender_competence dark neutral - sender_competence dark black 0.0629501 0.1409099 0.95 -0.2134912 0.3393913 0.4467399 1273 0.8256584
sender_competence dark neutral - sender_warmth dark black -0.3214916 0.1409099 0.95 -0.5979328 -0.0450504 -2.2815395 1273 0.1508783
sender_competence dark neutral - sender_competence light black -0.3905820 0.1441944 0.95 -0.6734667 -0.1076972 -2.7087186 1273 0.0748051
sender_competence dark neutral - sender_warmth light black 0.2170839 0.1441944 0.95 -0.0658008 0.4999687 1.5054952 1273 0.3321978
sender_competence dark neutral - sender_competence yellow white -0.1812456 0.1409448 0.95 -0.4577552 0.0952639 -1.2859339 1273 0.4457183
sender_competence dark neutral - sender_warmth yellow white -0.0200282 0.1409448 0.95 -0.2965377 0.2564814 -0.1420993 1273 0.9338793
sender_competence dark neutral - sender_competence dark white -0.0827023 0.1407841 0.95 -0.3588967 0.1934921 -0.5874407 1273 0.7677733
sender_competence dark neutral - sender_warmth dark white 0.1281206 0.1407841 0.95 -0.1480738 0.4043149 0.9100499 1273 0.5845703
sender_competence dark neutral - sender_competence light white -0.0448308 0.1409448 0.95 -0.3213404 0.2316787 -0.3180739 1273 0.8810455
sender_competence dark neutral - sender_warmth light white -0.0448308 0.1409448 0.95 -0.3213404 0.2316787 -0.3180739 1273 0.8810455
sender_warmth dark neutral - sender_competence light neutral 0.0742746 0.1455352 0.95 -0.2112407 0.3597899 0.5103546 1273 0.8185386
sender_warmth dark neutral - sender_warmth light neutral -0.1365483 0.1455352 0.95 -0.4220636 0.1489670 -0.9382489 1273 0.5747579
sender_warmth dark neutral - sender_competence yellow black 0.2163847 0.1405744 0.95 -0.0593982 0.4921676 1.5392899 1273 0.3321978
sender_warmth dark neutral - sender_warmth yellow black -0.0192408 0.1405744 0.95 -0.2950238 0.2565421 -0.1368731 1273 0.9338793
sender_warmth dark neutral - sender_competence dark black 0.1497595 0.1409099 0.95 -0.1266817 0.4262008 1.0628030 1273 0.5248815
sender_warmth dark neutral - sender_warmth dark black -0.2346822 0.1409099 0.95 -0.5111234 0.0417591 -1.6654764 1273 0.3025477
sender_warmth dark neutral - sender_competence light black -0.3037726 0.1441944 0.95 -0.5866573 -0.0208878 -2.1066881 1273 0.1689689
sender_warmth dark neutral - sender_warmth light black 0.3038933 0.1441944 0.95 0.0210086 0.5867781 2.1075257 1273 0.1689689
sender_warmth dark neutral - sender_competence yellow white -0.0944362 0.1409448 0.95 -0.3709458 0.1820733 -0.6700230 1273 0.7399384
sender_warmth dark neutral - sender_warmth yellow white 0.0667813 0.1409448 0.95 -0.2097283 0.3432908 0.4738116 1273 0.8225815
sender_warmth dark neutral - sender_competence dark white 0.0041071 0.1407841 0.95 -0.2720873 0.2803015 0.0291731 1273 0.9896679
sender_warmth dark neutral - sender_warmth dark white 0.2149300 0.1407841 0.95 -0.0612644 0.4911243 1.5266637 1273 0.3321978
sender_warmth dark neutral - sender_competence light white 0.0419786 0.1409448 0.95 -0.2345310 0.3184881 0.2978370 1273 0.8810455
sender_warmth dark neutral - sender_warmth light white 0.0419786 0.1409448 0.95 -0.2345310 0.3184881 0.2978370 1273 0.8810455
sender_competence light neutral - sender_warmth light neutral -0.2108229 0.1392178 0.95 -0.4839443 0.0622986 -1.5143389 1273 0.3321978
sender_competence light neutral - sender_competence yellow black 0.1421101 0.1441889 0.95 -0.1407638 0.4249840 0.9855832 1273 0.5503599
sender_competence light neutral - sender_warmth yellow black -0.0935154 0.1441889 0.95 -0.3763894 0.1893585 -0.6485621 1273 0.7529617
sender_competence light neutral - sender_competence dark black 0.0754849 0.1407529 0.95 -0.2006481 0.3516180 0.5362941 1273 0.8034157
sender_competence light neutral - sender_warmth dark black -0.3089568 0.1407529 0.95 -0.5850898 -0.0328237 -2.1950303 1273 0.1580033
sender_competence light neutral - sender_competence light black -0.3780471 0.1407988 0.95 -0.6542704 -0.1018239 -2.6850160 1273 0.0749377
sender_competence light neutral - sender_warmth light black 0.2296188 0.1407988 0.95 -0.0466045 0.5058420 1.6308285 1273 0.3157121
sender_competence light neutral - sender_competence yellow white -0.1687108 0.1407102 0.95 -0.4447602 0.1073386 -1.1989947 1273 0.4531157
sender_competence light neutral - sender_warmth yellow white -0.0074933 0.1407102 0.95 -0.2835428 0.2685561 -0.0532536 1273 0.9845141
sender_competence light neutral - sender_competence dark white -0.0701675 0.1408775 0.95 -0.3465450 0.2062101 -0.4980745 1273 0.8223553
sender_competence light neutral - sender_warmth dark white 0.1406554 0.1408775 0.95 -0.1357222 0.4170329 0.9984236 1273 0.5503599
sender_competence light neutral - sender_competence light white -0.0322960 0.1407102 0.95 -0.3083454 0.2437534 -0.2295215 1273 0.8947010
sender_competence light neutral - sender_warmth light white -0.0322960 0.1407102 0.95 -0.3083454 0.2437534 -0.2295215 1273 0.8947010
sender_warmth light neutral - sender_competence yellow black 0.3529330 0.1441889 0.95 0.0700591 0.6358069 2.4477133 1273 0.1057224
sender_warmth light neutral - sender_warmth yellow black 0.1173074 0.1441889 0.95 -0.1655665 0.4001814 0.8135679 1273 0.6562354
sender_warmth light neutral - sender_competence dark black 0.2863078 0.1407529 0.95 0.0101747 0.5624408 2.0341171 1273 0.1954077
sender_warmth light neutral - sender_warmth dark black -0.0981339 0.1407529 0.95 -0.3742670 0.1779992 -0.6972073 1273 0.7216258
sender_warmth light neutral - sender_competence light black -0.1672243 0.1407988 0.95 -0.4434476 0.1089990 -1.1876822 1273 0.4554756
sender_warmth light neutral - sender_warmth light black 0.4404416 0.1407988 0.95 0.1642183 0.7166649 3.1281623 1273 0.0275237
sender_warmth light neutral - sender_competence yellow white 0.0421121 0.1407102 0.95 -0.2339374 0.3181615 0.2992821 1273 0.8810455
sender_warmth light neutral - sender_warmth yellow white 0.2033295 0.1407102 0.95 -0.0727199 0.4793790 1.4450232 1273 0.3611224
sender_warmth light neutral - sender_competence dark white 0.1406554 0.1408775 0.95 -0.1357222 0.4170329 0.9984236 1273 0.5503599
sender_warmth light neutral - sender_warmth dark white 0.3514783 0.1408775 0.95 0.0751007 0.6278558 2.4949216 1273 0.1057224
sender_warmth light neutral - sender_competence light white 0.1785268 0.1407102 0.95 -0.0975226 0.4545763 1.2687553 1273 0.4457183
sender_warmth light neutral - sender_warmth light white 0.1785268 0.1407102 0.95 -0.0975226 0.4545763 1.2687553 1273 0.4457183
sender_competence yellow black - sender_warmth yellow black -0.2356256 0.1392178 0.95 -0.5087470 0.0374959 -1.6924964 1273 0.3019956
sender_competence yellow black - sender_competence dark black -0.0666252 0.1410264 0.95 -0.3432950 0.2100446 -0.4724306 1273 0.8225815
sender_competence yellow black - sender_warmth dark black -0.4510669 0.1410264 0.95 -0.7277367 -0.1743971 -3.1984566 1273 0.0240668
sender_competence yellow black - sender_competence light black -0.5201573 0.1456771 0.95 -0.8059508 -0.2343637 -3.5706186 1273 0.0103174
sender_competence yellow black - sender_warmth light black 0.0875086 0.1456771 0.95 -0.1982849 0.3733022 0.6007029 1273 0.7668143
sender_competence yellow black - sender_competence yellow white -0.3108209 0.1407915 0.95 -0.5870299 -0.0346120 -2.2076676 1273 0.1580033
sender_competence yellow black - sender_warmth yellow white -0.1496035 0.1407915 0.95 -0.4258124 0.1266055 -1.0625883 1273 0.5248815
sender_competence yellow black - sender_competence dark white -0.2122776 0.1409542 0.95 -0.4888057 0.0642505 -1.5060038 1273 0.3321978
sender_competence yellow black - sender_warmth dark white -0.0014547 0.1409542 0.95 -0.2779829 0.2750734 -0.0103206 1273 0.9982919
sender_competence yellow black - sender_competence light white -0.1744061 0.1407915 0.95 -0.4506151 0.1018028 -1.2387544 1273 0.4457183
sender_competence yellow black - sender_warmth light white -0.1744061 0.1407915 0.95 -0.4506151 0.1018028 -1.2387544 1273 0.4457183
sender_warmth yellow black - sender_competence dark black 0.1690003 0.1410264 0.95 -0.1076694 0.4456701 1.1983595 1273 0.4531157
sender_warmth yellow black - sender_warmth dark black -0.2154413 0.1410264 0.95 -0.4921111 0.0612284 -1.5276665 1273 0.3321978
sender_warmth yellow black - sender_competence light black -0.2845317 0.1456771 0.95 -0.5703253 0.0012618 -1.9531674 1273 0.2101693
sender_warmth yellow black - sender_warmth light black 0.3231342 0.1456771 0.95 0.0373406 0.6089277 2.2181541 1273 0.1580033
sender_warmth yellow black - sender_competence yellow white -0.0751954 0.1407915 0.95 -0.3514044 0.2010136 -0.5340902 1273 0.8034157
sender_warmth yellow black - sender_warmth yellow white 0.0860221 0.1407915 0.95 -0.1901869 0.3622311 0.6109891 1273 0.7668143
sender_warmth yellow black - sender_competence dark white 0.0233480 0.1409542 0.95 -0.2531802 0.2998761 0.1656421 1273 0.9227440
sender_warmth yellow black - sender_warmth dark white 0.2341708 0.1409542 0.95 -0.0423573 0.5106989 1.6613253 1273 0.3025477
sender_warmth yellow black - sender_competence light white 0.0612194 0.1407915 0.95 -0.2149896 0.3374284 0.4348231 1273 0.8256584
sender_warmth yellow black - sender_warmth light white 0.0612194 0.1407915 0.95 -0.2149896 0.3374284 0.4348231 1273 0.8256584
sender_competence dark black - sender_warmth dark black -0.3844417 0.1392178 0.95 -0.6575632 -0.1113202 -2.7614416 1273 0.0687016
sender_competence dark black - sender_competence light black -0.4535321 0.1407030 0.95 -0.7295674 -0.1774967 -3.2233283 1273 0.0240668
sender_competence dark black - sender_warmth light black 0.1541338 0.1407030 0.95 -0.1219015 0.4301692 1.0954550 1273 0.5166575
sender_competence dark black - sender_competence yellow white -0.2441957 0.1392334 0.95 -0.5173478 0.0289564 -1.7538593 1273 0.2771221
sender_competence dark black - sender_warmth yellow white -0.0829782 0.1392334 0.95 -0.3561303 0.1901738 -0.5959653 1273 0.7668143
sender_competence dark black - sender_competence dark white -0.1456524 0.1392202 0.95 -0.4187787 0.1274739 -1.0462013 1273 0.5322001
sender_competence dark black - sender_warmth dark white 0.0651705 0.1392202 0.95 -0.2079559 0.3382968 0.4681106 1273 0.8225815
sender_competence dark black - sender_competence light white -0.1077809 0.1392334 0.95 -0.3809330 0.1653711 -0.7741028 1273 0.6716910
sender_competence dark black - sender_warmth light white -0.1077809 0.1392334 0.95 -0.3809330 0.1653711 -0.7741028 1273 0.6716910
sender_warmth dark black - sender_competence light black -0.0690904 0.1407030 0.95 -0.3451257 0.2069450 -0.4910368 1273 0.8223553
sender_warmth dark black - sender_warmth light black 0.5385755 0.1407030 0.95 0.2625402 0.8146109 3.8277465 1273 0.0069158
sender_warmth dark black - sender_competence yellow white 0.1402460 0.1392334 0.95 -0.1329061 0.4133980 1.0072727 1273 0.5503599
sender_warmth dark black - sender_warmth yellow white 0.3014634 0.1392334 0.95 0.0283114 0.5746155 2.1651667 1273 0.1612314
sender_warmth dark black - sender_competence dark white 0.2387893 0.1392202 0.95 -0.0343370 0.5119156 1.7151910 1273 0.2942821
sender_warmth dark black - sender_warmth dark white 0.4496122 0.1392202 0.95 0.1764858 0.7227385 3.2295029 1273 0.0240668
sender_warmth dark black - sender_competence light white 0.2766608 0.1392334 0.95 0.0035087 0.5498128 1.9870292 1273 0.2040445
sender_warmth dark black - sender_warmth light white 0.2766608 0.1392334 0.95 0.0035087 0.5498128 1.9870292 1273 0.2040445
sender_competence light black - sender_warmth light black 0.6076659 0.1392178 0.95 0.3345444 0.8807874 4.3648593 1273 0.0021038
sender_competence light black - sender_competence yellow white 0.2093363 0.1409519 0.95 -0.0671872 0.4858598 1.4851617 1273 0.3399279
sender_competence light black - sender_warmth yellow white 0.3705538 0.1409519 0.95 0.0940303 0.6470773 2.6289385 1273 0.0828908
sender_competence light black - sender_competence dark white 0.3078797 0.1407698 0.95 0.0317133 0.5840460 2.1871142 1273 0.1580033
sender_competence light black - sender_warmth dark white 0.5187025 0.1407698 0.95 0.2425362 0.7948689 3.6847567 1273 0.0091239
sender_competence light black - sender_competence light white 0.3457511 0.1409519 0.95 0.0692276 0.6222746 2.4529729 1273 0.1057224
sender_competence light black - sender_warmth light white 0.3457511 0.1409519 0.95 0.0692276 0.6222746 2.4529729 1273 0.1057224
sender_warmth light black - sender_competence yellow white -0.3983296 0.1409519 0.95 -0.6748531 -0.1218061 -2.8259970 1273 0.0647307
sender_warmth light black - sender_warmth yellow white -0.2371121 0.1409519 0.95 -0.5136356 0.0394114 -1.6822202 1273 0.3020005
sender_warmth light black - sender_competence dark white -0.2997862 0.1407698 0.95 -0.5759526 -0.0236199 -2.1296201 1273 0.1689689
sender_warmth light black - sender_warmth dark white -0.0889634 0.1407698 0.95 -0.3651297 0.1872030 -0.6319776 1273 0.7614131
sender_warmth light black - sender_competence light white -0.2619148 0.1409519 0.95 -0.5384383 0.0146087 -1.8581859 1273 0.2364907
sender_warmth light black - sender_warmth light white -0.2619148 0.1409519 0.95 -0.5384383 0.0146087 -1.8581859 1273 0.2364907
sender_competence yellow white - sender_warmth yellow white 0.1612175 0.1392178 0.95 -0.1119040 0.4343389 1.1580239 1273 0.4725242
sender_competence yellow white - sender_competence dark white 0.0985433 0.1392374 0.95 -0.1746166 0.3717033 0.7077362 1273 0.7188580
sender_competence yellow white - sender_warmth dark white 0.3093662 0.1392374 0.95 0.0362062 0.5825262 2.2218617 1273 0.1580033
sender_competence yellow white - sender_competence light white 0.1364148 0.1392178 0.95 -0.1367067 0.4095363 0.9798664 1273 0.5503599
sender_competence yellow white - sender_warmth light white 0.1364148 0.1392178 0.95 -0.1367067 0.4095363 0.9798664 1273 0.5503599
sender_warmth yellow white - sender_competence dark white -0.0626741 0.1392374 0.95 -0.3358341 0.2104858 -0.4501244 1273 0.8256584
sender_warmth yellow white - sender_warmth dark white 0.1481487 0.1392374 0.95 -0.1250113 0.4213087 1.0640010 1273 0.5248815
sender_warmth yellow white - sender_competence light white -0.0248027 0.1392178 0.95 -0.2979242 0.2483188 -0.1781575 1273 0.9186715
sender_warmth yellow white - sender_warmth light white -0.0248027 0.1392178 0.95 -0.2979242 0.2483188 -0.1781575 1273 0.9186715
sender_competence dark white - sender_warmth dark white 0.2108229 0.1392178 0.95 -0.0622986 0.4839443 1.5143389 1273 0.3321978
sender_competence dark white - sender_competence light white 0.0378715 0.1392374 0.95 -0.2352885 0.3110314 0.2719920 1273 0.8838813
sender_competence dark white - sender_warmth light white 0.0378715 0.1392374 0.95 -0.2352885 0.3110314 0.2719920 1273 0.8838813
sender_warmth dark white - sender_competence light white -0.1729514 0.1392374 0.95 -0.4461114 0.1002086 -1.2421334 1273 0.4457183
sender_warmth dark white - sender_warmth light white -0.1729514 0.1392374 0.95 -0.4461114 0.1002086 -1.2421334 1273 0.4457183
sender_competence light white - sender_warmth light white 0.0000000 0.1392178 0.95 -0.2731215 0.2731215 0.0000000 1273 1.0000000
model_parameters(
  emmeans::contrast(sc_m,"pairwise", by = c("emoji_color", "profile_pic")),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
)
contrast                          | emoji_color | profile_pic | Coefficient |   SE |         95% CI | t(1273.00) |      p
-------------------------------------------------------------------------------------------------------------------------
sender_competence - sender_warmth |      yellow |     neutral |        0.22 | 0.14 | [-0.05,  0.50] |       1.60 | 0.195 
sender_competence - sender_warmth |        dark |     neutral |       -0.09 | 0.14 | [-0.36,  0.19] |      -0.62 | 0.600 
sender_competence - sender_warmth |       light |     neutral |       -0.21 | 0.14 | [-0.48,  0.06] |      -1.51 | 0.195 
sender_competence - sender_warmth |      yellow |       black |       -0.24 | 0.14 | [-0.51,  0.04] |      -1.69 | 0.195 
sender_competence - sender_warmth |        dark |       black |       -0.38 | 0.14 | [-0.66, -0.11] |      -2.76 | 0.026 
sender_competence - sender_warmth |       light |       black |        0.61 | 0.14 | [ 0.33,  0.88] |       4.36 | < .001
sender_competence - sender_warmth |      yellow |       white |        0.16 | 0.14 | [-0.11,  0.43] |       1.16 | 0.318 
sender_competence - sender_warmth |        dark |       white |        0.21 | 0.14 | [-0.06,  0.48] |       1.51 | 0.195 
sender_competence - sender_warmth |       light |       white |    5.55e-17 | 0.14 | [-0.27,  0.27] |   3.99e-16 | > .999

p-value adjustment method: Benjamini & Hochberg (1995)
model_parameters(
  emmeans::contrast(sc_m, by = c("emoji_color", "profile_pic")),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
)
contrast                 | emoji_color | profile_pic | Coefficient |   SE |         95% CI | t(1273.00) |      p
----------------------------------------------------------------------------------------------------------------
sender_competence effect |      yellow |     neutral |        0.11 | 0.07 | [-0.02,  0.25] |       1.60 | 0.195 
sender_warmth effect     |      yellow |     neutral |       -0.11 | 0.07 | [-0.25,  0.02] |      -1.60 | 0.195 
sender_competence effect |        dark |     neutral |       -0.04 | 0.07 | [-0.18,  0.09] |      -0.62 | 0.600 
sender_warmth effect     |        dark |     neutral |        0.04 | 0.07 | [-0.09,  0.18] |       0.62 | 0.600 
sender_competence effect |       light |     neutral |       -0.11 | 0.07 | [-0.24,  0.03] |      -1.51 | 0.195 
sender_warmth effect     |       light |     neutral |        0.11 | 0.07 | [-0.03,  0.24] |       1.51 | 0.195 
sender_competence effect |      yellow |       black |       -0.12 | 0.07 | [-0.25,  0.02] |      -1.69 | 0.195 
sender_warmth effect     |      yellow |       black |        0.12 | 0.07 | [-0.02,  0.25] |       1.69 | 0.195 
sender_competence effect |        dark |       black |       -0.19 | 0.07 | [-0.33, -0.06] |      -2.76 | 0.026 
sender_warmth effect     |        dark |       black |        0.19 | 0.07 | [ 0.06,  0.33] |       2.76 | 0.026 
sender_competence effect |       light |       black |        0.30 | 0.07 | [ 0.17,  0.44] |       4.36 | < .001
sender_warmth effect     |       light |       black |       -0.30 | 0.07 | [-0.44, -0.17] |      -4.36 | < .001
sender_competence effect |      yellow |       white |        0.08 | 0.07 | [-0.06,  0.22] |       1.16 | 0.318 
sender_warmth effect     |      yellow |       white |       -0.08 | 0.07 | [-0.22,  0.06] |      -1.16 | 0.318 
sender_competence effect |        dark |       white |        0.11 | 0.07 | [-0.03,  0.24] |       1.51 | 0.195 
sender_warmth effect     |        dark |       white |       -0.11 | 0.07 | [-0.24,  0.03] |      -1.51 | 0.195 
sender_competence effect |       light |       white |    2.78e-17 | 0.07 | [-0.14,  0.14] |   3.99e-16 | > .999
sender_warmth effect     |       light |       white |   -2.78e-17 | 0.07 | [-0.14,  0.14] |  -3.99e-16 | > .999

p-value adjustment method: Benjamini & Hochberg (1995)

Relationship Quality Between Sender and Receiver

# General distribution
hist_boxplot(dfp$quality_relationship, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(dfp, aes(x = quality_relationship)) + 
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") + 
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

# ANOVA model fails the assumption of normally distributed residuals
anova_model <- 
  aov(quality_relationship ~ profile_pic * emoji_color + emoji_hand_type + texting_usage_s + Error(id),
      data = dfp)
residuals_anova <- anova_model$Within$residuals
qqPlot(residuals_anova)

346 184 
344 182 

Model

# Unlike linear mixed models or ANOVAs, which treat the ordinal data as continuous,
# CLMM reduces the assumptions about equal spacing between ordinal levels
# and provide more precise estimates of effects.

# Fit check
qr_logit <-
  clmm(
    quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible") # AIC 1978.10

# qr_clog <-
#   clmm(
#     quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + (1 | id),
#     data = dfp,
#     link = "cloglog",
#     Hess = TRUE,
#     nAGQ = 10) # Error

qr_prob <-
  clmm(
    quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    link = "probit",
    Hess = TRUE,
    nAGQ = 10) # AIC 1980.32

## Compare models:
compare_performance(qr_prob, qr_logit, rank = T)
# Comparison of Model Performance Indices

Name     | Model | R2 (cond.) | R2 (marg.) |  RMSE | Sigma | AIC weights | BIC weights | Performance-Score
----------------------------------------------------------------------------------------------------------
qr_prob  |  clmm |      0.360 |      0.206 | 5.035 | 1.000 |       0.236 |       0.236 |            50.00%
qr_logit |  clmm |      0.348 |      0.199 | 5.029 | 1.814 |       0.764 |       0.764 |            50.00%
performance_aic(qr_prob)
[1] 1982.143
performance_aic(qr_logit) # qr_logit had higher performance
[1] 1979.794
# Compare model with and without interaction

## Model without interaction
quality_base <-
  clmm(
    quality_relationship_f ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Check effects
RVAideMemoire::Anova.clmm(quality_base, type = "2")
Analysis of Deviance Table (Type II tests)

Response: quality_relationship_f
                LR Chisq Df          Pr(>Chisq)    
emoji_color        1.057  2              0.5894    
profile_pic        0.497  2              0.7801    
emoji_hand_type  121.101  2 <0.0000000000000002 ***
texting_usage_s    0.375  1              0.5403    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Model with interaction
quality_int <-
  clmm(
    quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Check effects: only significant interaction effect
RVAideMemoire::Anova.clmm(quality_int, type = "3")
Analysis of Deviance Table (Type III tests)

Response: quality_relationship_f
                        LR Chisq Df            Pr(>Chisq)    
emoji_color                0.000  2                1.0000    
profile_pic                0.000  2                1.0000    
emoji_hand_type          120.404  2 < 0.00000000000000022 ***
texting_usage_s            0.304  1                0.5815    
emoji_color:profile_pic   40.555  4         0.00000003323 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check comparison
anova(quality_base, quality_int)
Likelihood ratio tests of cumulative link models:
 
             formula:                                                                                              link: threshold:
quality_base quality_relationship_f ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1 | id) logit flexible  
quality_int  quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id) logit flexible  

             no.par    AIC  logLik LR.stat df    Pr(>Chisq)    
quality_base     14 2012.3 -992.17                             
quality_int      18 1979.8 -971.90  40.555  4 0.00000003323 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
tab_model(quality_int, 
        # file = "quality_int.doc",
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL,
          string.stat = "z",
          string.se = "SE",
          string.ci = "95% CI",
          string.est = "Log-Odds"
          )
  quality relationship f
Predictors Log-Odds SE 95% CI z p
1|2 -6.74 1.03 -8.77 – -4.71 -6.52 <0.001
2|3 -3.78 0.35 -4.47 – -3.09 -10.70 <0.001
3|4 -2.21 0.28 -2.77 – -1.65 -7.75 <0.001
4|5 -0.91 0.27 -1.43 – -0.39 -3.42 0.001
5|6 0.74 0.26 0.23 – 1.26 2.81 0.005
6|7 3.07 0.29 2.49 – 3.65 10.42 <0.001
emoji color [dark] -0.23 0.31 -0.83 – 0.38 -0.74 0.462
emoji color [light] 0.88 0.30 0.28 – 1.47 2.88 0.004
profile pic [black] -0.07 0.31 -0.67 – 0.54 -0.22 0.827
profile pic [white] 0.28 0.31 -0.32 – 0.87 0.90 0.366
emoji hand type [peace] -0.48 0.18 -0.83 – -0.13 -2.67 0.007
emoji hand type [thumbs] 1.69 0.20 1.29 – 2.09 8.25 <0.001
texting usage s -0.07 0.12 -0.31 – 0.17 -0.55 0.581
emoji color [dark] ×
profile pic [black]
1.31 0.45 0.43 – 2.19 2.92 0.003
emoji color [light] ×
profile pic [black]
-1.21 0.44 -2.06 – -0.36 -2.78 0.006
emoji color [dark] ×
profile pic [white]
-0.32 0.43 -1.16 – 0.52 -0.75 0.455
emoji color [light] ×
profile pic [white]
-0.81 0.43 -1.65 – 0.04 -1.87 0.062
Random Effects
σ2 3.29
τ00 id 0.75
ICC 0.19
N id 76
Observations 684
Marginal R2 / Conditional R2 0.199 / 0.348
AIC 1979.794

Compare full model

# Compare parsimonious model with full model

## Remove missing values from the dataframe in order to compare models
dfp_clean <- dfp %>% dplyr::select(quality_relationship_f, emoji_color, profile_pic, emoji_hand_type, texting_usage_s, emoji_usage1_s, emoji_usage2_s, skin_color_id_s, identification_level_s, cross1_white_nr_s, cross2_white_nr_s, att_mean_s, inj_white_s, inj_black_s, inj_yellow_s, inj_should_1_s, inj_importance_s, descriptive_norm_s, skin_tone_emoji_id_s, usage_skintone1_s, usage_skintone2_s, politic_left_right_s, id) %>% drop_na()

## Model with all variables
qr_full <-
  clmm(
    quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id),
    data = dfp_clean,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Parsimonious model with cleaned dataframe
qr_parsimonious <-
  clmm(
    quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
    data = dfp_clean,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

## Compare models: no significant difference between models.
anova(qr_parsimonious, qr_full)
Likelihood ratio tests of cumulative link models:
 
                formula:                                                                                                                                                                                                                                                                                                                                                                                                                                             link: threshold:
qr_parsimonious quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id)                                                                                                                                                                                                                                                                                                                                                logit flexible  
qr_full         quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id) logit flexible  

                no.par    AIC  logLik LR.stat df Pr(>Chisq)
qr_parsimonious     18 1459.1 -711.55                      
qr_full             35 1470.0 -700.01  23.087 17     0.1464

Quality check

# Multicollinearity for categorical predictors with an interaction
qr_multi <- lm(quality_relationship ~ emoji_color * profile_pic + emoji_hand_type + texting_usage_s, data = dfp)
car::vif(qr_multi, type = "predictor") # no issues
                    GVIF Df GVIF^(1/(2*Df)) Interacts With                          Other Predictors
emoji_color     1.402264  8        1.021355    profile_pic          emoji_hand_type, texting_usage_s
profile_pic     1.402264  8        1.021355    emoji_color          emoji_hand_type, texting_usage_s
emoji_hand_type 1.402264  2        1.088197           --   emoji_color, profile_pic, texting_usage_s
texting_usage_s 1.000000  1        1.000000           --   emoji_color, profile_pic, emoji_hand_type
# Random effects' normality
qr_random_effects <- as.vector(ranef(quality_int)$id$`(Intercept)`)
qqPlot(qr_random_effects) # no issues

[1]  2 76
# Proportional odds assumption
qr_clm <-
  clm(
    quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s,
    data = dfp,
    Hess = TRUE,
    nAGQ = 10,
    link = "logit",
    threshold = "flexible"
  )

nominal_test(qr_clm) # no issues
Tests of nominal effects

formula: quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s
                        Df  logLik    AIC     LRT Pr(>Chi)   
<none>                     -997.99 2030.0                    
emoji_color             10 -994.94 2043.9  6.1087 0.806051   
profile_pic             10 -994.56 2043.1  6.8638 0.738238   
emoji_hand_type         10 -994.69 2043.4  6.6110 0.761586   
texting_usage_s          5 -987.88 2019.8 20.2235 0.001135 **
emoji_color:profile_pic                                      
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
scale_test(qr_clm) # no issues
Tests of scale effects

formula: quality_relationship_f ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s
                        Df  logLik    AIC     LRT Pr(>Chi)
<none>                     -997.99 2030.0                 
emoji_color              2 -997.78 2033.6 0.42684   0.8078
profile_pic              2 -997.52 2033.0 0.94078   0.6248
emoji_hand_type          2 -997.98 2034.0 0.02081   0.9896
texting_usage_s          1 -997.86 2031.7 0.27685   0.5988
emoji_color:profile_pic  8 -996.51 2043.0 2.96025   0.9368
# Harrell Plot
table(dfp$quality_relationship) # the minimum response registered was "1"

  1   2   3   4   5   6   7 
  1  17  52 101 197 230  86 
qr_func <- function(y) {
  c(
    'Y>=1' = qlogis(mean(y >= 1)),
    'Y>=2' = qlogis(mean(y >= 2)),
    'Y>=3' = qlogis(mean(y >= 3)),
    'Y>=4' = qlogis(mean(y >= 4)),
    'Y>=5' = qlogis(mean(y >= 5)),
    'Y>=6' = qlogis(mean(y >= 6)),
    'Y>=7' = qlogis(mean(y >= 7))
  )
}

qr_sf <-
  with(
    dfp,
    summary(
      quality_relationship_f ~ emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
      fun = qr_func
    )
  )
qr_sf
quality_relationship_f      N= 684  

+---------------+---------------+---+----+--------+--------+--------+---------+-----------+---------+
|               |               |  N|Y>=1|    Y>=2|    Y>=3|    Y>=4|     Y>=5|       Y>=6|     Y>=7|
+---------------+---------------+---+----+--------+--------+--------+---------+-----------+---------+
|    emoji_color|         yellow|228| Inf|     Inf|3.452253|2.094330|1.1944941|-0.03509132|-1.707342|
|               |           dark|228| Inf|5.424950|3.797734|2.397895|1.2192403|-0.05264373|-1.812379|
|               |          light|228| Inf|     Inf|3.610918|2.050171|0.8979416|-0.37267529|-2.397895|
+---------------+---------------+---+----+--------+--------+--------+---------+-----------+---------+
|    profile_pic|        neutral|228| Inf|     Inf|4.317488|2.397895|1.2192403|-0.10536052|-2.007468|
|               |          black|228| Inf|5.424950|3.314186|2.140066|1.0753554|-0.24686008|-1.776492|
|               |          white|228| Inf|     Inf|3.452253|2.007468|1.0071199|-0.10536052|-2.050171|
+---------------+---------------+---+----+--------+--------+--------+---------+-----------+---------+
|emoji_hand_type|             ok|228| Inf|5.424950|3.610918|2.288196|1.0986123|-0.46430561|-2.456736|
|               |          peace|228| Inf|     Inf|2.982002|1.459156|0.3908663|-0.83479770|-3.081910|
|               |         thumbs|228| Inf|     Inf|5.424950|3.610918|2.2368337| 0.83479770|-1.075355|
+---------------+---------------+---+----+--------+--------+--------+---------+-----------+---------+
|texting_usage_s|[-2.412,-0.304)|171| Inf|     Inf|5.135798|2.203739|1.2869219| 0.03509132|-2.021548|
|               |[-0.304, 0.325)|171| Inf|     Inf|3.314186|2.203739|0.9122007|-0.15234072|-2.021548|
|               |[ 0.325, 0.768)|180| Inf|     Inf|2.833213|2.136965|1.0691984|-0.26826399|-1.778856|
|               |[ 0.768, 1.064]|162| Inf|5.081404|5.081404|2.143520|1.1486227|-0.22314355|-1.960095|
+---------------+---------------+---+----+--------+--------+--------+---------+-----------+---------+
|         1 | id|           TRUE|684| Inf|6.526495|3.610918|2.171500|1.0986123|-0.15234072|-1.939243|
+---------------+---------------+---+----+--------+--------+--------+---------+-----------+---------+
|        Overall|               |684| Inf|6.526495|3.610918|2.171500|1.0986123|-0.15234072|-1.939243|
+---------------+---------------+---+----+--------+--------+--------+---------+-----------+---------+
plot(
  qr_sf,
  which = 1:7,
  pch = 1:7,
  xlab = 'logit',
  main = 'Harrell Plot',
  xlim = range(-4, 7.5)
) # no issues

Post-hoc comparisons

# Calculate the predicted values
qr_emm <- emmeans(quality_int, ~ emoji_color * profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(qr_emm, by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral -0.2169323 0.1735207 0.95 -0.5570265 0.1231620 -1.2501809 Inf 0.2376376
dark effect neutral -0.4433344 0.1840859 0.95 -0.8041361 -0.0825327 -2.4083022 Inf 0.0360605
light effect neutral 0.6602667 0.1825882 0.95 0.3024003 1.0181331 3.6161512 Inf 0.0013456
yellow effect black -0.2506713 0.1874369 0.95 -0.6180409 0.1166982 -1.3373639 Inf 0.2376376
dark effect black 0.8325205 0.1791353 0.95 0.4814217 1.1836193 4.6474392 Inf 0.0000302
light effect black -0.5818492 0.1830303 0.95 -0.9405819 -0.2231164 -3.1789780 Inf 0.0044339
yellow effect white 0.1587815 0.1761202 0.95 -0.1864078 0.5039708 0.9015516 Inf 0.3672951
dark effect white -0.3880936 0.1738294 0.95 -0.7287930 -0.0473942 -2.2326119 Inf 0.0460342
light effect white 0.2293121 0.1755107 0.95 -0.1146825 0.5733068 1.3065420 Inf 0.2376376
model_parameters(
  emmeans::contrast(qr_emm, by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral effect yellow -0.0695464 0.1763922 0.95 -0.4152687 0.2761759 -0.3942714 Inf 0.6933807
black effect yellow -0.1369160 0.1797044 0.95 -0.4891302 0.2152982 -0.7618956 Inf 0.5735859
white effect yellow 0.2064624 0.1777202 0.95 -0.1418629 0.5547877 1.1617269 Inf 0.3680196
neutral effect dark -0.3992534 0.1794414 0.95 -0.7509521 -0.0475547 -2.2249789 Inf 0.0469488
black effect dark 0.8429709 0.1809799 0.95 0.4882569 1.1976850 4.6578163 Inf 0.0000288
white effect dark -0.4437175 0.1742988 0.95 -0.7853370 -0.1020981 -2.5457287 Inf 0.0245362
neutral effect light 0.6021353 0.1739036 0.95 0.2612905 0.9429802 3.4624654 Inf 0.0016058
black effect light -0.6736111 0.1756847 0.95 -1.0179468 -0.3292754 -3.8342043 Inf 0.0005669
white effect light 0.0714758 0.1776084 0.95 -0.2766303 0.4195818 0.4024346 Inf 0.6933807
model_parameters(
  emmeans::contrast(qr_emm, interaction = TRUE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
emoji_color_eff profile_pic_eff Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral effect -0.1139916 0.1437261 0.95 -0.3956894 0.1677063 -0.7931169 Inf 0.4277097
dark effect neutral effect -0.4436986 0.1481275 0.95 -0.7340232 -0.1533740 -2.9953827 Inf 0.0061673
light effect neutral effect 0.5576901 0.1453281 0.95 0.2728522 0.8425281 3.8374545 Inf 0.0003729
yellow effect black effect -0.1477306 0.1492075 0.95 -0.4401719 0.1447106 -0.9901021 Inf 0.4141597
dark effect black effect 0.8321563 0.1481995 0.95 0.5416907 1.1226220 5.6151093 Inf 0.0000002
light effect black effect -0.6844257 0.1464397 0.95 -0.9714422 -0.3974093 -4.6737729 Inf 0.0000133
yellow effect white effect 0.2617222 0.1449803 0.95 -0.0224340 0.5458784 1.8052257 Inf 0.1065591
dark effect white effect -0.3884577 0.1434063 0.95 -0.6695288 -0.1073866 -2.7087922 Inf 0.0121552
light effect white effect 0.1267356 0.1467668 0.95 -0.1609221 0.4143932 0.8635166 Inf 0.4277097
model_parameters(
  emmeans::contrast(qr_emm, "pairwise", by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow - dark neutral 0.2264022 0.3076615 0.95 -0.3766033 0.8294077 0.7358807 Inf 0.5195287
yellow - light neutral -0.8771989 0.3049724 0.95 -1.4749339 -0.2794640 -2.8763222 Inf 0.0090526
dark - light neutral -1.1036011 0.3230212 0.95 -1.7367111 -0.4704911 -3.4164970 Inf 0.0019539
yellow - dark black -1.0831918 0.3177169 0.95 -1.7059054 -0.4604782 -3.4092989 Inf 0.0019539
yellow - light black 0.3311778 0.3243083 0.95 -0.3044547 0.9668104 1.0211822 Inf 0.3949304
dark - light black 1.4143696 0.3099137 0.95 0.8069500 2.0217893 4.5637535 Inf 0.0000452
yellow - dark white 0.5468751 0.3027639 0.95 -0.0465313 1.1402815 1.8062755 Inf 0.1063130
yellow - light white -0.0705306 0.3056600 0.95 -0.6696132 0.5285519 -0.2307486 Inf 0.8175101
dark - light white -0.6174057 0.3017002 0.95 -1.2087272 -0.0260842 -2.0464214 Inf 0.0732869
model_parameters(
  emmeans::contrast(qr_emm, "revpairwise", by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
dark - yellow neutral -0.2264022 0.3076615 0.95 -0.8294077 0.3766033 -0.7358807 Inf 0.5195287
light - yellow neutral 0.8771989 0.3049724 0.95 0.2794640 1.4749339 2.8763222 Inf 0.0090526
light - dark neutral 1.1036011 0.3230212 0.95 0.4704911 1.7367111 3.4164970 Inf 0.0019539
dark - yellow black 1.0831918 0.3177169 0.95 0.4604782 1.7059054 3.4092989 Inf 0.0019539
light - yellow black -0.3311778 0.3243083 0.95 -0.9668104 0.3044547 -1.0211822 Inf 0.3949304
light - dark black -1.4143696 0.3099137 0.95 -2.0217893 -0.8069500 -4.5637535 Inf 0.0000452
dark - yellow white -0.5468751 0.3027639 0.95 -1.1402815 0.0465313 -1.8062755 Inf 0.1063130
light - yellow white 0.0705306 0.3056600 0.95 -0.5285519 0.6696132 0.2307486 Inf 0.8175101
light - dark white 0.6174057 0.3017002 0.95 0.0260842 1.2087272 2.0464214 Inf 0.0732869
model_parameters(
  emmeans::contrast(qr_emm, "pairwise", by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral - black yellow 0.0673696 0.3085956 0.95 -0.5374667 0.6722060 0.2183104 Inf 0.8837063
neutral - white yellow -0.2760088 0.3051289 0.95 -0.8740505 0.3220330 -0.9045643 Inf 0.4701809
black - white yellow -0.3433784 0.3108732 0.95 -0.9526786 0.2659219 -1.1045610 Inf 0.4040248
neutral - black dark -1.2422243 0.3154771 0.95 -1.8605481 -0.6239006 -3.9376056 Inf 0.0002469
neutral - white dark 0.0444641 0.3039818 0.95 -0.5513292 0.6402575 0.1462724 Inf 0.8837063
black - white dark 1.2866885 0.3067057 0.95 0.6855565 1.8878205 4.1951900 Inf 0.0001227
neutral - black light 1.2757464 0.3011153 0.95 0.6855712 1.8659216 4.2367368 Inf 0.0001227
neutral - white light 0.5306596 0.3044820 0.95 -0.0661143 1.1274334 1.7428271 Inf 0.1464549
black - white light -0.7450869 0.3075341 0.95 -1.3478427 -0.1423310 -2.4227778 Inf 0.0346553
model_parameters(
  emmeans::contrast(qr_emm, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow neutral - dark neutral 0.2264022 0.3076615 0.95 -0.3766033 0.8294077 0.7358807 Inf 0.5937471
yellow neutral - light neutral -0.8771989 0.3049724 0.95 -1.4749339 -0.2794640 -2.8763222 Inf 0.0144842
yellow neutral - yellow black 0.0673696 0.3085956 0.95 -0.5374667 0.6722060 0.2183104 Inf 0.8508212
yellow neutral - dark black -1.0158222 0.3087075 0.95 -1.6208778 -0.4107666 -3.2905652 Inf 0.0044994
yellow neutral - light black 0.3985475 0.3058060 0.95 -0.2008212 0.9979162 1.3032691 Inf 0.3149720
yellow neutral - yellow white -0.2760088 0.3051289 0.95 -0.8740505 0.3220330 -0.9045643 Inf 0.4892874
yellow neutral - dark white 0.2708663 0.3002380 0.95 -0.3175894 0.8593221 0.9021719 Inf 0.4892874
yellow neutral - light white -0.3465394 0.3040398 0.95 -0.9424464 0.2493676 -1.1397830 Inf 0.3981549
dark neutral - light neutral -1.1036011 0.3230212 0.95 -1.7367111 -0.4704911 -3.4164970 Inf 0.0033495
dark neutral - yellow black -0.1590325 0.3074334 0.95 -0.7615909 0.4435258 -0.5172911 Inf 0.7025260
dark neutral - dark black -1.2422243 0.3154771 0.95 -1.8605481 -0.6239006 -3.9376056 Inf 0.0007407
dark neutral - light black 0.1721453 0.3165098 0.95 -0.4482025 0.7924931 0.5438862 Inf 0.7025260
dark neutral - yellow white -0.5024109 0.3119004 0.95 -1.1137245 0.1089026 -1.6108058 Inf 0.1929997
dark neutral - dark white 0.0444641 0.3039818 0.95 -0.5513292 0.6402575 0.1462724 Inf 0.8837063
dark neutral - light white -0.5729416 0.3096867 0.95 -1.1799164 0.0340333 -1.8500681 Inf 0.1361726
light neutral - yellow black 0.9445686 0.3177937 0.95 0.3217044 1.5674327 2.9722698 Inf 0.0118243
light neutral - dark black -0.1386232 0.3058770 0.95 -0.7381311 0.4608847 -0.4531993 Inf 0.7317059
light neutral - light black 1.2757464 0.3011153 0.95 0.6855712 1.8659216 4.2367368 Inf 0.0003272
light neutral - yellow white 0.6011902 0.3048378 0.95 0.0037191 1.1986613 1.9721641 Inf 0.1093295
light neutral - dark white 1.1480653 0.3029983 0.95 0.5541996 1.7419310 3.7890159 Inf 0.0010890
light neutral - light white 0.5306596 0.3044820 0.95 -0.0661143 1.1274334 1.7428271 Inf 0.1541630
yellow black - dark black -1.0831918 0.3177169 0.95 -1.7059054 -0.4604782 -3.4092989 Inf 0.0033495
yellow black - light black 0.3311778 0.3243083 0.95 -0.3044547 0.9668104 1.0211822 Inf 0.4423221
yellow black - yellow white -0.3433784 0.3108732 0.95 -0.9526786 0.2659219 -1.1045610 Inf 0.4040248
yellow black - dark white 0.2034967 0.3065700 0.95 -0.3973695 0.8043629 0.6637853 Inf 0.6291654
yellow black - light white -0.4139090 0.3098950 0.95 -1.0212921 0.1934741 -1.3356426 Inf 0.3114276
dark black - light black 1.4143696 0.3099137 0.95 0.8069500 2.0217893 4.5637535 Inf 0.0001809
dark black - yellow white 0.7398134 0.3100656 0.95 0.1320960 1.3475308 2.3859900 Inf 0.0510996
dark black - dark white 1.2866885 0.3067057 0.95 0.6855565 1.8878205 4.1951900 Inf 0.0003272
dark black - light white 0.6692828 0.3082830 0.95 0.0650591 1.2735064 2.1710011 Inf 0.0769657
light black - yellow white -0.6745562 0.3088519 0.95 -1.2798948 -0.0692177 -2.1840770 Inf 0.0769657
light black - dark white -0.1276812 0.3010877 0.95 -0.7178022 0.4624399 -0.4240663 Inf 0.7325645
light black - light white -0.7450869 0.3075341 0.95 -1.3478427 -0.1423310 -2.4227778 Inf 0.0504077
yellow white - dark white 0.5468751 0.3027639 0.95 -0.0465313 1.1402815 1.8062755 Inf 0.1417506
yellow white - light white -0.0705306 0.3056600 0.95 -0.6696132 0.5285519 -0.2307486 Inf 0.8508212
dark white - light white -0.6174057 0.3017002 0.95 -1.2087272 -0.0260842 -2.0464214 Inf 0.0977158
model_parameters(
  emmeans::contrast(qr_emm, method = "revpairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
dark neutral - yellow neutral -0.2264022 0.3076615 0.95 -0.8294077 0.3766033 -0.7358807 Inf 0.5937471
light neutral - yellow neutral 0.8771989 0.3049724 0.95 0.2794640 1.4749339 2.8763222 Inf 0.0144842
light neutral - dark neutral 1.1036011 0.3230212 0.95 0.4704911 1.7367111 3.4164970 Inf 0.0033495
yellow black - yellow neutral -0.0673696 0.3085956 0.95 -0.6722060 0.5374667 -0.2183104 Inf 0.8508212
yellow black - dark neutral 0.1590325 0.3074334 0.95 -0.4435258 0.7615909 0.5172911 Inf 0.7025260
yellow black - light neutral -0.9445686 0.3177937 0.95 -1.5674327 -0.3217044 -2.9722698 Inf 0.0118243
dark black - yellow neutral 1.0158222 0.3087075 0.95 0.4107666 1.6208778 3.2905652 Inf 0.0044994
dark black - dark neutral 1.2422243 0.3154771 0.95 0.6239006 1.8605481 3.9376056 Inf 0.0007407
dark black - light neutral 0.1386232 0.3058770 0.95 -0.4608847 0.7381311 0.4531993 Inf 0.7317059
dark black - yellow black 1.0831918 0.3177169 0.95 0.4604782 1.7059054 3.4092989 Inf 0.0033495
light black - yellow neutral -0.3985475 0.3058060 0.95 -0.9979162 0.2008212 -1.3032691 Inf 0.3149720
light black - dark neutral -0.1721453 0.3165098 0.95 -0.7924931 0.4482025 -0.5438862 Inf 0.7025260
light black - light neutral -1.2757464 0.3011153 0.95 -1.8659216 -0.6855712 -4.2367368 Inf 0.0003272
light black - yellow black -0.3311778 0.3243083 0.95 -0.9668104 0.3044547 -1.0211822 Inf 0.4423221
light black - dark black -1.4143696 0.3099137 0.95 -2.0217893 -0.8069500 -4.5637535 Inf 0.0001809
yellow white - yellow neutral 0.2760088 0.3051289 0.95 -0.3220330 0.8740505 0.9045643 Inf 0.4892874
yellow white - dark neutral 0.5024109 0.3119004 0.95 -0.1089026 1.1137245 1.6108058 Inf 0.1929997
yellow white - light neutral -0.6011902 0.3048378 0.95 -1.1986613 -0.0037191 -1.9721641 Inf 0.1093295
yellow white - yellow black 0.3433784 0.3108732 0.95 -0.2659219 0.9526786 1.1045610 Inf 0.4040248
yellow white - dark black -0.7398134 0.3100656 0.95 -1.3475308 -0.1320960 -2.3859900 Inf 0.0510996
yellow white - light black 0.6745562 0.3088519 0.95 0.0692177 1.2798948 2.1840770 Inf 0.0769657
dark white - yellow neutral -0.2708663 0.3002380 0.95 -0.8593221 0.3175894 -0.9021719 Inf 0.4892874
dark white - dark neutral -0.0444641 0.3039818 0.95 -0.6402575 0.5513292 -0.1462724 Inf 0.8837063
dark white - light neutral -1.1480653 0.3029983 0.95 -1.7419310 -0.5541996 -3.7890159 Inf 0.0010890
dark white - yellow black -0.2034967 0.3065700 0.95 -0.8043629 0.3973695 -0.6637853 Inf 0.6291654
dark white - dark black -1.2866885 0.3067057 0.95 -1.8878205 -0.6855565 -4.1951900 Inf 0.0003272
dark white - light black 0.1276812 0.3010877 0.95 -0.4624399 0.7178022 0.4240663 Inf 0.7325645
dark white - yellow white -0.5468751 0.3027639 0.95 -1.1402815 0.0465313 -1.8062755 Inf 0.1417506
light white - yellow neutral 0.3465394 0.3040398 0.95 -0.2493676 0.9424464 1.1397830 Inf 0.3981549
light white - dark neutral 0.5729416 0.3096867 0.95 -0.0340333 1.1799164 1.8500681 Inf 0.1361726
light white - light neutral -0.5306596 0.3044820 0.95 -1.1274334 0.0661143 -1.7428271 Inf 0.1541630
light white - yellow black 0.4139090 0.3098950 0.95 -0.1934741 1.0212921 1.3356426 Inf 0.3114276
light white - dark black -0.6692828 0.3082830 0.95 -1.2735064 -0.0650591 -2.1710011 Inf 0.0769657
light white - light black 0.7450869 0.3075341 0.95 0.1423310 1.3478427 2.4227778 Inf 0.0504077
light white - yellow white 0.0705306 0.3056600 0.95 -0.5285519 0.6696132 0.2307486 Inf 0.8508212
light white - dark white 0.6174057 0.3017002 0.95 0.0260842 1.2087272 2.0464214 Inf 0.0977158
# Covariate
qr_emm_co <- emmeans(quality_int, ~ emoji_hand_type)
model_parameters(
  emmeans::contrast(qr_emm_co, "revpairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) 
contrast       | Coefficient |   SE |         95% CI |     z |      p
---------------------------------------------------------------------
peace - ok     |       -0.48 | 0.18 | [-0.83, -0.13] | -2.67 | 0.007 
thumbs - ok    |        1.69 | 0.20 | [ 1.29,  2.09] |  8.25 | < .001
thumbs - peace |        2.17 | 0.21 | [ 1.75,  2.58] | 10.28 | < .001

p-value adjustment method: Benjamini & Hochberg (1995)
model_parameters(
  emmeans::contrast(qr_emm_co, "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
)
contrast       | Coefficient |   SE |         95% CI |      z |      p
----------------------------------------------------------------------
ok - peace     |        0.48 | 0.18 | [ 0.13,  0.83] |   2.67 | 0.007 
ok - thumbs    |       -1.69 | 0.20 | [-2.09, -1.29] |  -8.25 | < .001
peace - thumbs |       -2.17 | 0.21 | [-2.58, -1.75] | -10.28 | < .001

p-value adjustment method: Benjamini & Hochberg (1995)

Plot

# Estimated means plot

# Generate interaction-style plot for estimated marginal means
qr_plot <- emmip(quality_int, ~ emoji_color * profile_pic, CIs = TRUE, mode = "mean.class")
qr_df_p <- qr_plot$data

qr_df_p <- qr_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color),
         profile_pic = str_to_title(profile_pic))

qr_df_p$profile_pic <- factor(qr_df_p$profile_pic, levels = c("Neutral",
                                                              "Black",
                                                              "White"))

quality_pploto <-
  ggplot(qr_df_p, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(qr_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)) +
  labs(x = "Profile Picture\n", y = "Estimated Relationship Quality Ratings\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    limits = c(4.6, 6),
    breaks = seq(4.6, 6, 0.2),
    position = "right"
  ) +
  scale_color_manual(values = colors, guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + 
  scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 
quality_pploto

# Save plot
# ggsave(filename = "quality_pplot.svg", width = 216, height = 131, unit = "mm", dpi = 300)
rm(list = ls(pattern = "^qr_"), anova_model, residuals_anova, dfp_clean, original_range, estimated_range, scaling_factor)

Senders Racialized Identity in the Neutral Condition

# Prepare dataframe to only include neutral profiles
datra <- dfp %>% dplyr::filter(profile_pic == "neutral")

# Compute index of participant's confident level about sender's racialized profile
datra$confident_level <- datra$sender_black - datra$sender_white
# General distribution
hist_boxplot(datra$confident_level, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(datra, aes(x = confident_level)) + 
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") + 
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

table(datra$confident_level)

 -6  -5  -4  -3  -2  -1   0   1   2   3   4   6 
  7   4  11   8  16   7 139   4   9   5  10   8 
# ANOVA model fails the assumption of normally distributed residuals
anova_model <- aov(confident_level ~ emoji_color + emoji_hand_type + texting_usage_s + Error(id), 
                   data = datra)
residuals_anova <- anova_model$Within$residuals
qqPlot(residuals_anova)

107 139 
105 137 

Model

# Linear Mixed-Effects Model using Gaussian link results in singular model
sr_lmer <- lmer(confident_level ~ emoji_color + emoji_hand_type + texting_usage_s + (1|id), 
                data = datra)

Subtracting the responses from the questions ‘How certain are you that the sender is Black?’ and ‘How certain are you that the sender is White?’ resulted in a large number of zeros, indicating that many participants responded with the same value for both questions.

However, this results in a challenge for data analysis due to the extreme unbalanced distribution. To address this, one possible strategy involves initially comparing zero and non-zero responses to identify any biased patterns that might justify participants’ decisions to provide zero as an answer. Subsequently, if any issues arise, we can exclude all the zero responses and focus solely on analyzing the non-zero responses.

PART I: Examine the zero responses

## Check zero inflation
datra$confident_level_test <- abs(datra$confident_level)
table(datra$confident_level_test)

  0   1   2   3   4   5   6 
139  11  25  13  21   4  15 
sr_glmer <- glmer(confident_level_test ~ emoji_color + emoji_hand_type + texting_usage_s + (1|id),
                 family=poisson,
                 data = datra)
check_zeroinflation(sr_glmer)
# Check for zero-inflation

   Observed zeros: 139
  Predicted zeros: 105
            Ratio: 0.76
## Transform data so zero, which is the focus, is 1, and non-zero is 0.
datra$confident_level_zero <- ifelse(datra$confident_level == 0, 1, 0)
table(datra$confident_level_zero)

  0   1 
 89 139 
# Check proportions
datra %>% dplyr::group_by(emoji_color) %>% summarise(mean=mean(confident_level_zero))
# A tibble: 3 × 2
  emoji_color  mean
  <fct>       <dbl>
1 yellow      0.724
2 dark        0.5  
3 light       0.605
## Run binomial model
sender_racialized_model_zero <- 
  glmer(confident_level_zero ~ emoji_color + emoji_hand_type + texting_usage_s + (1|id), 
        data = datra, 
        family = "binomial")

# Check effects
Anova(sender_racialized_model_zero, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: confident_level_zero
                 Chisq Df Pr(>Chisq)   
emoji_color     9.3238  2   0.009449 **
emoji_hand_type 2.6650  2   0.263814   
texting_usage_s 0.0572  1   0.811048   
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Check summary
tab_model(sender_racialized_model_zero, 
        # file = "sender_racialized_model_zero.doc",
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL,
          string.stat = "z",
          string.se = "SE",
          string.ci = "95% CI",
          string.est = "Log-Odds"
          )
  confident level zero
Predictors Log-Odds SE 95% CI z p
(Intercept) 1.86 0.56 0.76 – 2.95 3.33 0.001
emoji color [dark] -1.45 0.50 -2.44 – -0.47 -2.89 0.004
emoji color [light] -0.91 0.50 -1.89 – 0.07 -1.81 0.070
emoji hand type [peace] -0.77 0.50 -1.75 – 0.20 -1.55 0.121
emoji hand type [thumbs] -0.22 0.63 -1.47 – 1.02 -0.35 0.725
texting usage s 0.07 0.27 -0.47 – 0.60 0.24 0.811
Random Effects
σ2 3.29
τ00 id 3.18
ICC 0.49
N id 76
Observations 228
Marginal R2 / Conditional R2 0.072 / 0.528
AIC 285.479
# Check quality of the model
sr_check <- simulateResiduals(sender_racialized_model_zero, plot = T)
plot(sr_check)

# Calculate the predicted values
sr_emm <- emmeans(sender_racialized_model_zero, ~ emoji_color)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(sr_emm),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow effect 0.7884313 0.2702630 0.95 0.2587256 1.3181370 2.9172747 Inf 0.0105931
dark effect -0.6661983 0.3274703 0.95 -1.3080283 -0.0243683 -2.0343776 Inf 0.0628703
light effect -0.1222330 0.3264884 0.95 -0.7621385 0.5176724 -0.3743871 Inf 0.7081163
model_parameters(
  emmeans::contrast(sr_emm, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow - dark 1.4546296 0.5039475 0.95 0.4669106 2.4423486 2.8864705 Inf 0.0116877
yellow - light 0.9106644 0.5020325 0.95 -0.0733013 1.8946301 1.8139549 Inf 0.1045270
dark - light -0.5439652 0.5955005 0.95 -1.7111248 0.6231943 -0.9134589 Inf 0.3610012
# Estimated means plot

## Generate interaction-style plot for estimated marginal means
sr_plot <- emmip(sender_racialized_model_zero, ~ emoji_color, CIs = TRUE, type = "response")
sr_df_p <- sr_plot$data

sr_df_p <- sr_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color))

sender_racialized_pplot <-
  ggplot(sr_df_p, aes(
    x = emoji_color,
    y = yvar,
    color = emoji_color, shape = emoji_color
  )) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Emojis\n", y = "Estimated Zero Patterns\n") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'none',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip()
sender_racialized_pplot

PART II: Examine the non-zero responses

The confident_level was calculated as datra$sender_black - datra$sender_white, which means that negative values indicate a higher confidence that the sender is White; and positive values indicate a higher confidence that the sender is Black.

# Transform data so only non-zero are included
datra$confident_level_nonzero <- ifelse(datra$confident_level == 0, NA, datra$confident_level)
table(datra$confident_level_nonzero)

-6 -5 -4 -3 -2 -1  1  2  3  4  6 
 7  4 11  8 16  7  4  9  5 10  8 
sum(!is.na(datra$confident_level_nonzero))
[1] 89
# Run model
sender_racialized_model_nonzero <- 
  lmer(confident_level_nonzero ~ emoji_color + emoji_hand_type + texting_usage_s + (1|id), 
       data = datra)

# Check effects
Anova(sender_racialized_model_nonzero, type = "2") 
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: confident_level_nonzero
                  Chisq Df         Pr(>Chisq)    
emoji_color     60.0253  2 0.0000000000000924 ***
emoji_hand_type  0.3673  2             0.8322    
texting_usage_s  0.2709  1             0.6027    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Check summary
tab_model(sender_racialized_model_nonzero, 
        # file = "sender_racialized_model_nonzero.doc",
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL,
          string.stat = "t",
          string.se = "SE",
          string.ci = "95% CI",
          string.est = "Coefficient"
          )
  confident level nonzero
Predictors Coefficient SE 95% CI t p
(Intercept) -2.36 0.75 -3.84 – -0.87 -3.16 0.002
emoji color [dark] 4.68 0.73 3.22 – 6.14 6.38 <0.001
emoji color [light] -1.03 0.76 -2.53 – 0.48 -1.36 0.178
emoji hand type [peace] 0.41 0.73 -1.05 – 1.88 0.56 0.575
emoji hand type [thumbs] 0.17 0.91 -1.64 – 1.99 0.19 0.850
texting usage s -0.15 0.29 -0.72 – 0.42 -0.52 0.604
Random Effects
σ2 6.02
τ00 id 0.48
ICC 0.07
N id 48
Observations 89
Marginal R2 / Conditional R2 0.529 / 0.564
AIC 426.239
# Check quality of the model
check_predictions(sender_racialized_model_nonzero)

sr_check_nonzero <- simulateResiduals(sender_racialized_model_nonzero, plot = T)
plot(sr_check_nonzero)

# Calculate the predicted values
sr_emm_nonzero <- emmeans(sender_racialized_model_nonzero, ~ emoji_color)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(sr_emm_nonzero),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high t df_error p
yellow effect -1.218668 0.4227380 0.95 -2.062830 -0.374506 -2.882797 65.42543 0.0053281
dark effect 3.464223 0.4525251 0.95 2.559494 4.368952 7.655316 61.50720 0.0000000
light effect -2.245555 0.4646063 0.95 -3.175100 -1.316010 -4.833242 59.39632 0.0000148
model_parameters(
  emmeans::contrast(sr_emm_nonzero, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high t df_error p
yellow - dark -4.682891 0.7423704 0.95 -6.1655617 -3.200220 -6.308025 64.87354 0.0000000
yellow - light 1.026887 0.7644305 0.95 -0.5010237 2.554797 1.343336 62.33682 0.1840334
dark - light 5.709778 0.8139832 0.95 4.0810508 7.338504 7.014614 59.08634 0.0000000
model_parameters(
  emmeans::contrast(sr_emm_nonzero, method = "revpairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high t df_error p
dark - yellow 4.682891 0.7423704 0.95 3.200220 6.1655617 6.308025 64.87354 0.0000000
light - yellow -1.026887 0.7644305 0.95 -2.554797 0.5010237 -1.343336 62.33682 0.1840334
light - dark -5.709778 0.8139832 0.95 -7.338504 -4.0810508 -7.014614 59.08634 0.0000000
# Check if all levels of emoji colors are different from 0
# Subset the data for each level of emoji_color
data_dark <- datra$confident_level_nonzero[datra$emoji_color == "dark"]
data_light <- datra$confident_level_nonzero[datra$emoji_color == "light"]
data_yellow <- datra$confident_level_nonzero[datra$emoji_color == "yellow"]

# Run the Anderson-Darling test for normality
ad.test(data_dark)

    Anderson-Darling normality test

data:  data_dark
A = 1.2154, p-value = 0.003137
ad.test(data_light)

    Anderson-Darling normality test

data:  data_light
A = 0.83676, p-value = 0.0273
ad.test(data_yellow)

    Anderson-Darling normality test

data:  data_yellow
A = 0.66774, p-value = 0.0696
# Perform Wilcoxon signed-rank test for each subset against 0
# Note: Using paired = FALSE for one-sample scenario
test_dark <- wilcox.test(data_dark, mu = 0, paired = FALSE, exact = FALSE); test_dark

    Wilcoxon signed rank test with continuity correction

data:  data_dark
V = 651, p-value = 0.00004396
alternative hypothesis: true location is not equal to 0
test_light <- wilcox.test(data_light, mu = 0, paired = FALSE, exact = FALSE); test_light

    Wilcoxon signed rank test with continuity correction

data:  data_light
V = 19.5, p-value = 0.00001122
alternative hypothesis: true location is not equal to 0
test_yellow <- wilcox.test(data_yellow, mu = 0, paired = FALSE, exact = FALSE); test_yellow

    Wilcoxon signed rank test with continuity correction

data:  data_yellow
V = 30, p-value = 0.002844
alternative hypothesis: true location is not equal to 0
de <- c(test_dark$p.value,
            test_light$p.value,
            test_yellow$p.value)

fdrs <- p.adjust(de, method = "BH")
fdrs
[1] 0.00006593533 0.00003364574 0.00284447387
# Check medians
datra %>% dplyr::group_by(emoji_color) %>% summarise(median=median(confident_level_nonzero,na.rm = TRUE))
# A tibble: 3 × 2
  emoji_color median
  <fct>        <dbl>
1 yellow          -2
2 dark             3
3 light           -3

Compare full model

# Compare parsimonious model with full model

## Remove missing values from the dataframe in order to compare models
datra_clean <- datra %>% dplyr::select(confident_level_nonzero, emoji_color, emoji_hand_type, texting_usage_s, emoji_usage1_s, emoji_usage2_s, skin_color_id_s, identification_level_s, cross1_white_nr_s, cross2_white_nr_s, att_mean_s, inj_white_s, inj_black_s, inj_yellow_s, inj_should_1_s, inj_importance_s, descriptive_norm_s, skin_tone_emoji_id_s, usage_skintone1_s, usage_skintone2_s, politic_left_right_s, id) %>% drop_na()

## Model with all variables
sr_full <- lmer(confident_level_nonzero ~ 1 + emoji_color + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id), data = datra_clean)

## Parsimonious model with cleaned dataframe
sr_parsimonious <- lmer(confident_level_nonzero ~ 1 + emoji_color + emoji_hand_type + texting_usage_s + (1 | id), data = datra_clean)

## Compare models: no significant difference between models.
anova(sr_parsimonious, sr_full)
Data: datra_clean
Models:
sr_parsimonious: confident_level_nonzero ~ 1 + emoji_color + emoji_hand_type + texting_usage_s + (1 | id)
sr_full: confident_level_nonzero ~ 1 + emoji_color + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id)
                npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)
sr_parsimonious    8 342.06 360.05 -163.03   326.06                     
sr_full           25 357.60 413.81 -153.80   307.60 18.464 17     0.3602

Plot

# Estimated means plot

## Generate interaction-style plot for estimated marginal means
sr_plot <- emmip(sender_racialized_model_nonzero, ~ emoji_color, CIs = TRUE, type = "response")
sr_df_p <- sr_plot$data

sr_df_p <- sr_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color))

sender_racialized_pplot <-
  ggplot(sr_df_p, aes(
    x = emoji_color,
    y = yvar,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = 0,
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Emojis\n", y = "Estimated Confidence Levels Regarding\n Senders' Racialized Identity on Neutral Conditions\n") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'none',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    limits = c(-4.5, 4.5),
    breaks = seq(-4.5, 4.5, 1.5),
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip()  +
  annotate("text", x = Inf, y = Inf, label = "Black", hjust = 1.5, vjust = 1.9, color = "gray40") +
  annotate("text", x = Inf, y = -Inf, label = "White", hjust = -0.4, vjust = 1.9, color = "gray40")
sender_racialized_pplot

# Save plot
# ggsave(filename = "sender_racialized_pplot.svg", width = 216, height = 131, unit = "mm", dpi = 300)
rm(list = ls(pattern = "sr_"), anova_model, residuals_anova, datra_clean, de, test_dark, test_light, test_yellow, data_dark, data_light, data_yellow)

Dwell Time on Emojis’ and Profile Pictures’ AOI

Zero duration dwell times will be removed to ensure dwell time analysis is not contaminated by skippings (Horstmann et al., 2016). As per pre-registration, unreasonable gazes (±2 standard deviations) will be removed.

Emojis’ AOI

# General distribution
hist_boxplot(dfe$ia_dwell_time, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(dfe, aes(x = ia_dwell_time)) +
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") +
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

# Remove zero values
sum(!is.na(dfe$ia_dwell_time)) # total of data points
[1] 684
sum(dfe$ia_dwell_time == 0) # total of data points with zero
[1] 77
dfe$ia_dwell_time[dfe$ia_dwell_time == 0] <- NA
sum(!is.na(dfe$ia_dwell_time)) # remaining data points
[1] 607
# Remove outliers
## Identify values less than mean - 2*SD or greater than mean + 2*SD
dw_mean_val <- mean(dfe$ia_dwell_time, na.rm = TRUE)
dw_std_dev <- sd(dfe$ia_dwell_time, na.rm = TRUE)
dw_outliers <- which(dfe$ia_dwell_time < (dw_mean_val - 2 * dw_std_dev) | dfe$ia_dwell_time > (dw_mean_val + 2 * dw_std_dev))
length(dw_outliers)
[1] 17
dfe$ia_dwell_time[dw_outliers] # values in milliseconds
 [1]  6482  3691  3757  6099  4190  3644  3460  3029  3073  3127  3453  3221  3148  3603  5235 12365  2642
## Recode outliers as NA
sum(!is.na(dfe$ia_dwell_time)) # total of data points
[1] 607
dfe$ia_dwell_time[dw_outliers] <- NA
sum(!is.na(dfe$ia_dwell_time)) # remaining data points
[1] 590
# ANOVA model fails the assumption of normally distributed residuals
anova_model <- 
  aov(ia_dwell_time ~ profile_pic * emoji_color + emoji_hand_type + texting_usage_s + Error(id),
      data = dfe)
residuals_anova <- anova_model$Within$residuals
qqPlot(residuals_anova)

145 494 
143 492 

Model

# Linear Mixed-Effects Model is not a good fit
dw_lmer <- 
  lmer(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
       data = dfe)
check_predictions(dw_lmer)

dw_check_lmer <- simulateResiduals(dw_lmer, plot = T)
plot(dw_check_lmer)

# Generalized Linear Mixed-Effects Model

## Base model without interaction
dwell_emoji_base <- 
  glmmTMB(ia_dwell_time ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = Gamma(link = "log"), 
          data = dfe)

## Check effects
Anova(dwell_emoji_base, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_dwell_time
                  Chisq Df Pr(>Chisq)    
emoji_color     15.2986  2  0.0004764 ***
profile_pic      0.6368  2  0.7273097    
emoji_hand_type  2.0089  2  0.3662443    
texting_usage_s  5.6920  1  0.0170429 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
tab_model(dwell_emoji_base,
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL)
  ia dwell time
Predictors Estimates std. Error CI Statistic p
(Intercept) 6.41 0.08 6.26 – 6.57 80.58 <0.001
emoji color [dark] 0.27 0.07 0.13 – 0.41 3.86 <0.001
emoji color [light] 0.17 0.07 0.03 – 0.32 2.38 0.017
profile pic [black] 0.05 0.07 -0.08 – 0.18 0.72 0.473
profile pic [white] 0.00 0.07 -0.13 – 0.14 0.04 0.968
emoji hand type [peace] 0.03 0.07 -0.10 – 0.16 0.45 0.656
emoji hand type [thumbs] -0.07 0.07 -0.21 – 0.07 -0.98 0.328
texting usage s -0.09 0.04 -0.16 – -0.02 -2.39 0.017
Random Effects
σ2 0.44
τ00 id 0.05
ICC 0.10
N id 76
Observations 590
Marginal R2 / Conditional R2 0.046 / 0.137
AIC 8801.368
summary(dwell_emoji_base)
 Family: Gamma  ( log )
Formula:          ia_dwell_time ~ 1 + emoji_color + profile_pic + emoji_hand_type +      texting_usage_s + (1 | id)
Data: dfe

     AIC      BIC   logLik deviance df.resid 
  8801.4   8845.2  -4390.7   8781.4      580 

Random effects:

Conditional model:
 Groups Name        Variance Std.Dev.
 id     (Intercept) 0.04636  0.2153  
Number of obs: 590, groups:  id, 76

Dispersion estimate for Gamma family (sigma^2): 0.438 

Conditional model:
                       Estimate Std. Error z value             Pr(>|z|)    
(Intercept)            6.411126   0.079562   80.58 < 0.0000000000000002 ***
emoji_colordark        0.268908   0.069605    3.86             0.000112 ***
emoji_colorlight       0.172981   0.072781    2.38             0.017467 *  
profile_picblack       0.048781   0.067916    0.72             0.472599    
profile_picwhite       0.002673   0.067581    0.04             0.968454    
emoji_hand_typepeace   0.030320   0.068096    0.45             0.656141    
emoji_hand_typethumbs -0.071415   0.073042   -0.98             0.328212    
texting_usage_s       -0.087388   0.036629   -2.39             0.017043 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Model with interaction
dwell_emoji_int <- 
  glmmTMB(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = Gamma(link = "log"), 
          data = dfe)

## Check effects
Anova(dwell_emoji_int, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: ia_dwell_time
                            Chisq Df            Pr(>Chisq)    
(Intercept)             4615.1830  1 < 0.00000000000000022 ***
emoji_color                7.8467  2             0.0197745 *  
profile_pic                3.0765  2             0.2147558    
emoji_hand_type            1.8517  2             0.3961990    
texting_usage_s            5.4336  1             0.0197532 *  
emoji_color:profile_pic   20.2296  4             0.0004499 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Compare models: 
anova(dwell_emoji_base, dwell_emoji_int)
Data: dfe
Models:
dwell_emoji_base: ia_dwell_time ~ 1 + emoji_color + profile_pic + emoji_hand_type + , zi=~0, disp=~1
dwell_emoji_base:     texting_usage_s + (1 | id), zi=~0, disp=~1
dwell_emoji_int: ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dwell_emoji_int:     texting_usage_s + (1 | id), zi=~0, disp=~1
                 Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)    
dwell_emoji_base 10 8801.4 8845.2 -4390.7   8781.4                             
dwell_emoji_int  14 8789.6 8850.9 -4380.8   8761.6 19.798      4  0.0005473 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
tab_model(dwell_emoji_int,
        # file = "dwell_emoji_int.doc",
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL,
          string.stat = "z",
          string.se = "SE",
          string.ci = "95% CI",
          string.est = "Log-Prevalence"
          )
  ia dwell time
Predictors Log-Prevalence SE 95% CI z p
(Intercept) 6.38 0.09 6.19 – 6.56 67.94 <0.001
emoji color [dark] 0.28 0.12 0.05 – 0.52 2.40 0.016
emoji color [light] 0.27 0.11 0.04 – 0.49 2.35 0.019
profile pic [black] 0.18 0.12 -0.06 – 0.41 1.48 0.138
profile pic [white] -0.01 0.11 -0.24 – 0.21 -0.12 0.908
emoji hand type [peace] 0.02 0.07 -0.12 – 0.15 0.26 0.798
emoji hand type [thumbs] -0.08 0.08 -0.23 – 0.07 -1.07 0.283
texting usage s -0.09 0.04 -0.16 – -0.01 -2.33 0.020
emoji color [dark] ×
profile pic [black]
-0.32 0.17 -0.66 – 0.02 -1.84 0.066
emoji color [light] ×
profile pic [black]
-0.10 0.17 -0.43 – 0.23 -0.59 0.557
emoji color [dark] ×
profile pic [white]
0.24 0.16 -0.08 – 0.56 1.46 0.144
emoji color [light] ×
profile pic [white]
-0.21 0.16 -0.53 – 0.11 -1.31 0.191
Random Effects
σ2 0.42
τ00 id 0.05
ICC 0.10
N id 76
Observations 590
Marginal R2 / Conditional R2 0.073 / 0.170
AIC 8789.570

Compare full model

# Compare parsimonious model with full model

# Step 1

## Remove missing values from the dataframe in order to compare models
dfe_clean <- dfe %>% dplyr::select(ia_dwell_time, profile_pic, emoji_color, emoji_hand_type, texting_usage_s, emoji_usage1_s, emoji_usage2_s, skin_color_id_s, identification_level_s, cross1_white_nr_s, cross2_white_nr_s, att_mean_s, inj_white_s, inj_black_s, inj_yellow_s, inj_should_1_s, inj_importance_s, descriptive_norm_s, skin_tone_emoji_id_s, usage_skintone1_s, usage_skintone2_s, politic_left_right_s, id) %>% drop_na()

## Model with all variables
dw_full <- glmmTMB(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id), family = Gamma(link = "log"), data = dfe_clean)

## Parsimonious model with cleaned dataframe
dw_parsimonious <- glmmTMB(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfe_clean)

## Compare models
anova(dw_parsimonious, dw_full)
Data: dfe_clean
Models:
dw_parsimonious: ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_parsimonious:     texting_usage_s + (1 | id), zi=~0, disp=~1
dw_full: ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_full:     texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + , zi=~0, disp=~1
dw_full:     identification_level_s + cross1_white_nr_s + cross2_white_nr_s + , zi=~0, disp=~1
dw_full:     att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + , zi=~0, disp=~1
dw_full:     inj_importance_s + inj_importance_s + descriptive_norm_s + , zi=~0, disp=~1
dw_full:     skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + , zi=~0, disp=~1
dw_full:     politic_left_right_s + (1 | id), zi=~0, disp=~1
                Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)   
dw_parsimonious 14 6334.7 6391.4 -3153.3   6306.7                            
dw_full         31 6330.6 6456.3 -3134.3   6268.6 38.037     17   0.002429 **
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
summary(dw_full)
 Family: Gamma  ( log )
Formula:          ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type +      texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s +      identification_level_s + cross1_white_nr_s + cross2_white_nr_s +      att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s +      inj_importance_s + inj_importance_s + descriptive_norm_s +      skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s +      politic_left_right_s + (1 | id)
Data: dfe_clean

     AIC      BIC   logLik deviance df.resid 
  6330.6   6456.3  -3134.3   6268.6      395 

Random effects:

Conditional model:
 Groups Name        Variance      Std.Dev. 
 id     (Intercept) 0.00000001182 0.0001087
Number of obs: 426, groups:  id, 55

Dispersion estimate for Gamma family (sigma^2): 0.425 

Conditional model:
                                   Estimate Std. Error z value            Pr(>|z|)    
(Intercept)                        6.364431   0.103900   61.26 <0.0000000000000002 ***
emoji_colordark                    0.330297   0.137710    2.40              0.0165 *  
emoji_colorlight                   0.264245   0.133458    1.98              0.0477 *  
profile_picblack                   0.207904   0.138538    1.50              0.1334    
profile_picwhite                   0.067890   0.135153    0.50              0.6154    
emoji_hand_typepeace              -0.027258   0.081751   -0.33              0.7388    
emoji_hand_typethumbs             -0.078323   0.087116   -0.90              0.3686    
texting_usage_s                   -0.110369   0.045033   -2.45              0.0143 *  
emoji_usage1_s                    -0.019620   0.056338   -0.35              0.7276    
emoji_usage2_s                     0.027780   0.053617    0.52              0.6044    
skin_color_id_s                    0.065632   0.038969    1.68              0.0921 .  
identification_level_s             0.115697   0.046099    2.51              0.0121 *  
cross1_white_nr_s                  0.043748   0.058947    0.74              0.4580    
cross2_white_nr_s                 -0.016735   0.057680   -0.29              0.7717    
att_mean_s                         0.002672   0.049225    0.05              0.9567    
inj_white_s                       -0.038069   0.042170   -0.90              0.3667    
inj_black_s                        0.101140   0.042878    2.36              0.0183 *  
inj_yellow_s                       0.014644   0.044548    0.33              0.7424    
inj_should_1_s                    -0.021029   0.039735   -0.53              0.5967    
inj_importance_s                   0.079463   0.043520    1.83              0.0679 .  
descriptive_norm_s                -0.052557   0.058201   -0.90              0.3665    
skin_tone_emoji_id_s               0.013996   0.047104    0.30              0.7664    
usage_skintone1_s                 -0.096267   0.052870   -1.82              0.0686 .  
usage_skintone2_s                 -0.141984   0.073023   -1.94              0.0519 .  
politic_left_right_s              -0.016908   0.041144   -0.41              0.6811    
emoji_colordark:profile_picblack  -0.383716   0.201599   -1.90              0.0570 .  
emoji_colorlight:profile_picblack -0.068568   0.195004   -0.35              0.7251    
emoji_colordark:profile_picwhite   0.252141   0.192510    1.31              0.1903    
emoji_colorlight:profile_picwhite -0.231664   0.190026   -1.22              0.2228    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Step 2

## Remove missing values from the dataframe in order to compare models
dfe_clean <- dfe %>% dplyr::select(ia_dwell_time, profile_pic, emoji_color, emoji_hand_type, texting_usage_s, identification_level_s, inj_black_s, id) %>% drop_na()

## Model with all variables
dw_full <- 
  glmmTMB(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s +  identification_level_s + inj_black_s + (1 | id), 
          family = Gamma(link = "log"), 
          data = dfe_clean)

## Parsimonious model with cleaned dataframe
dw_parsimonious <- glmmTMB(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfe_clean)

## Compare models
anova(dw_parsimonious, dw_full)
Data: dfe_clean
Models:
dw_parsimonious: ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_parsimonious:     texting_usage_s + (1 | id), zi=~0, disp=~1
dw_full: ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_full:     texting_usage_s + identification_level_s + inj_black_s + , zi=~0, disp=~1
dw_full:     (1 | id), zi=~0, disp=~1
                Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)
dw_parsimonious 14 8789.6 8850.9 -4380.8   8761.6                         
dw_full         16 8789.1 8859.1 -4378.5   8757.1 4.5079      2      0.105

Quality check

# Check fit
check_predictions(dwell_emoji_int)

# Residuals
ypred <- predict(dwell_emoji_int)
res <- residuals(dwell_emoji_int, type = 'deviance')
plot(ypred,res)

hist(res)

dw_check <- simulateResiduals(dwell_emoji_int, plot = T)
plot(dw_check)

testDispersion(dw_check)


    DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated

data:  simulationOutput
dispersion = 0.97004, p-value = 0.848
alternative hypothesis: two.sided
testOutliers(dw_check)


    DHARMa outlier test based on exact binomial test with approximate expectations

data:  dw_check
outliers at both margin(s) = 2, observations = 590, p-value = 0.3459
alternative hypothesis: true probability of success is not equal to 0.007968127
95 percent confidence interval:
 0.0004107882 0.0121911349
sample estimates:
frequency of outliers (expected: 0.00796812749003984 ) 
                                           0.003389831 

Post-hoc comparisons

# Base model
dw_emm_be <- emmeans(dwell_emoji_base, ~ emoji_color)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(dw_emm_be),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow effect -0.1472963 0.0407790 0.95 -0.2272216 -0.0673709 -3.6120629 Inf 0.0009113
dark effect 0.1216115 0.0408623 0.95 0.0415228 0.2017002 2.9761273 Inf 0.0043787
light effect 0.0256848 0.0426673 0.95 -0.0579416 0.1093112 0.6019778 Inf 0.5471889
model_parameters(
  emmeans::contrast(dw_emm_be, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow - dark -0.2689078 0.0696047 0.95 -0.4053304 -0.1324851 -3.863357 Inf 0.0003355
yellow - light -0.1729810 0.0727813 0.95 -0.3156298 -0.0303323 -2.376723 Inf 0.0262008
dark - light 0.0959267 0.0729214 0.95 -0.0469966 0.2388501 1.315481 Inf 0.1883484
# Calculate the predicted values
dw_emm_e <- emmeans(dwell_emoji_int, ~ emoji_color * profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(dw_emm_e, by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral -0.1840629 0.0657096 0.95 -0.3128512 -0.0552745 -2.8011585 Inf 0.0152758
dark effect neutral 0.1000802 0.0708991 0.95 -0.0388794 0.2390398 1.4115869 Inf 0.2371075
light effect neutral 0.0839827 0.0685098 0.95 -0.0502940 0.2182594 1.2258496 Inf 0.2698996
yellow effect black -0.0446386 0.0741253 0.95 -0.1899216 0.1006444 -0.6022047 Inf 0.5470379
dark effect black -0.0802275 0.0682665 0.95 -0.2140273 0.0535724 -1.1752099 Inf 0.2698996
light effect black 0.1248661 0.0728962 0.95 -0.0180079 0.2677400 1.7129298 Inf 0.1561058
yellow effect white -0.1938347 0.0669831 0.95 -0.3251191 -0.0625503 -2.8937865 Inf 0.0152758
dark effect white 0.3307700 0.0676407 0.95 0.1981967 0.4633434 4.8901048 Inf 0.0000091
light effect white -0.1369353 0.0672074 0.95 -0.2686593 -0.0052113 -2.0375046 Inf 0.0935989
model_parameters(
  emmeans::contrast(dw_emm_e, by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral effect yellow -0.0548730 0.0671633 0.95 -0.1865106 0.0767646 -0.8170093 Inf 0.5170194
black effect yellow 0.1229995 0.0702678 0.95 -0.0147228 0.2607219 1.7504395 Inf 0.1440765
white effect yellow -0.0681265 0.0672982 0.95 -0.2000286 0.0637756 -1.0123073 Inf 0.4670867
neutral effect dark -0.0284496 0.0693984 0.95 -0.1644679 0.1075687 -0.4099464 Inf 0.6818453
black effect dark -0.1703090 0.0697592 0.95 -0.3070345 -0.0335834 -2.4413833 Inf 0.0438934
white effect dark 0.1987586 0.0678308 0.95 0.0658127 0.3317045 2.9302121 Inf 0.0304858
neutral effect light 0.0483560 0.0653856 0.95 -0.0797975 0.1765095 0.7395505 Inf 0.5170194
black effect light 0.1276877 0.0677134 0.95 -0.0050281 0.2604034 1.8857084 Inf 0.1335021
white effect light -0.1760437 0.0671471 0.95 -0.3076495 -0.0444378 -2.6217619 Inf 0.0393644
model_parameters(
  emmeans::contrast(dw_emm_e, interaction = TRUE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
emoji_color_eff profile_pic_eff Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral effect -0.0432175 0.0549577 0.95 -0.1509326 0.0644976 -0.7863769 Inf 0.4856025
dark effect neutral effect -0.0167941 0.0568564 0.95 -0.1282306 0.0946425 -0.2953767 Inf 0.7677061
light effect neutral effect 0.0600115 0.0544785 0.95 -0.0467644 0.1667875 1.1015631 Inf 0.4059775
yellow effect black effect 0.0962068 0.0583199 0.95 -0.0180981 0.2105116 1.6496399 Inf 0.1782299
dark effect black effect -0.1971017 0.0568663 0.95 -0.3085577 -0.0856457 -3.4660520 Inf 0.0023767
light effect black effect 0.1008949 0.0565445 0.95 -0.0099303 0.2117202 1.7843448 Inf 0.1673272
yellow effect white effect -0.0529893 0.0551707 0.95 -0.1611220 0.0551433 -0.9604606 Inf 0.4330587
dark effect white effect 0.2138958 0.0549769 0.95 0.1061431 0.3216485 3.8906505 Inf 0.0008998
light effect white effect -0.1609065 0.0556594 0.95 -0.2699970 -0.0518160 -2.8909109 Inf 0.0115238
model_parameters(
  emmeans::contrast(dw_emm_e, method = "pairwise", by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral - black yellow -0.1778725 0.1198661 0.95 -0.4128057 0.0570607 -1.4839270 Inf 0.2067424
neutral - white yellow 0.0132535 0.1146401 0.95 -0.2114370 0.2379440 0.1156096 Inf 0.9079620
black - white yellow 0.1911260 0.1200930 0.95 -0.0442519 0.4265040 1.5914835 Inf 0.2007015
neutral - black dark 0.1418594 0.1215070 0.95 -0.0962900 0.3800087 1.1674996 Inf 0.3124397
neutral - white dark -0.2272082 0.1181861 0.95 -0.4588487 0.0044323 -1.9224615 Inf 0.1227324
black - white dark -0.3690676 0.1188217 0.95 -0.6019538 -0.1361814 -3.1060624 Inf 0.0170637
neutral - black light -0.0793317 0.1149436 0.95 -0.3046170 0.1459537 -0.6901791 Inf 0.5513418
neutral - white light 0.2243996 0.1139426 0.95 0.0010762 0.4477231 1.9694089 Inf 0.1227324
black - white light 0.3037313 0.1179508 0.95 0.0725521 0.5349106 2.5750690 Inf 0.0450990
model_parameters(
  emmeans::contrast(dw_emm_e, method = "pairwise", by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow - dark neutral -0.2841431 0.1183015 0.95 -0.5160098 -0.0522763 -2.4018542 Inf 0.0420954
yellow - light neutral -0.2680456 0.1140000 0.95 -0.4914814 -0.0446097 -2.3512775 Inf 0.0420954
dark - light neutral 0.0160975 0.1229748 0.95 -0.2249286 0.2571236 0.1309009 Inf 0.8958537
yellow - dark black 0.0355888 0.1224578 0.95 -0.2044240 0.2756017 0.2906213 Inf 0.8677586
yellow - light black -0.1695047 0.1302173 0.95 -0.4247258 0.0857164 -1.3017071 Inf 0.2895248
dark - light black -0.2050936 0.1202239 0.95 -0.4407280 0.0305409 -1.7059304 Inf 0.1584379
yellow - dark white -0.5246048 0.1166497 0.95 -0.7532341 -0.2959755 -4.4972651 Inf 0.0000619
yellow - light white -0.0568994 0.1158959 0.95 -0.2840512 0.1702524 -0.4909526 Inf 0.8015914
dark - light white 0.4677054 0.1170361 0.95 0.2383188 0.6970919 3.9962482 Inf 0.0002896
model_parameters(
  emmeans::contrast(dw_emm_e, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow neutral - dark neutral -0.2841431 0.1183015 0.95 -0.5160098 -0.0522763 -2.4018542 Inf 0.0533854
yellow neutral - light neutral -0.2680456 0.1140000 0.95 -0.4914814 -0.0446097 -2.3512775 Inf 0.0561272
yellow neutral - yellow black -0.1778725 0.1198661 0.95 -0.4128057 0.0570607 -1.4839270 Inf 0.2611483
yellow neutral - dark black -0.1422837 0.1168787 0.95 -0.3713617 0.0867943 -1.2173621 Inf 0.3497736
yellow neutral - light black -0.3473772 0.1179519 0.95 -0.5785588 -0.1161957 -2.9450743 Inf 0.0193726
yellow neutral - yellow white 0.0132535 0.1146401 0.95 -0.2114370 0.2379440 0.1156096 Inf 0.9079620
yellow neutral - dark white -0.5113513 0.1161345 0.95 -0.7389707 -0.2837319 -4.4030960 Inf 0.0001921
yellow neutral - light white -0.0436459 0.1151519 0.95 -0.2693395 0.1820477 -0.3790289 Inf 0.7687270
dark neutral - light neutral 0.0160975 0.1229748 0.95 -0.2249286 0.2571236 0.1309009 Inf 0.9079620
dark neutral - yellow black 0.1062705 0.1194795 0.95 -0.1279049 0.3404460 0.8894460 Inf 0.4983512
dark neutral - dark black 0.1418594 0.1215070 0.95 -0.0962900 0.3800087 1.1674996 Inf 0.3645130
dark neutral - light black -0.0632342 0.1249174 0.95 -0.3080678 0.1815995 -0.5062078 Inf 0.7013924
dark neutral - yellow white 0.2973966 0.1189659 0.95 0.0642277 0.5305654 2.4998470 Inf 0.0496988
dark neutral - dark white -0.2272082 0.1181861 0.95 -0.4588487 0.0044323 -1.9224615 Inf 0.1227324
dark neutral - light white 0.2404972 0.1201765 0.95 0.0049556 0.4760387 2.0012001 Inf 0.1166679
light neutral - yellow black 0.0901730 0.1243655 0.95 -0.1535788 0.3339248 0.7250650 Inf 0.5814772
light neutral - dark black 0.1257619 0.1160251 0.95 -0.1016432 0.3531669 1.0839193 Inf 0.3854777
light neutral - light black -0.0793317 0.1149436 0.95 -0.3046170 0.1459537 -0.6901791 Inf 0.5880979
light neutral - yellow white 0.2812991 0.1150931 0.95 0.0557207 0.5068774 2.4440994 Inf 0.0522771
light neutral - dark white -0.2433057 0.1167647 0.95 -0.4721604 -0.0144511 -2.0837261 Inf 0.1029741
light neutral - light white 0.2243996 0.1139426 0.95 0.0010762 0.4477231 1.9694089 Inf 0.1173748
yellow black - dark black 0.0355888 0.1224578 0.95 -0.2044240 0.2756017 0.2906213 Inf 0.8167139
yellow black - light black -0.1695047 0.1302173 0.95 -0.4247258 0.0857164 -1.3017071 Inf 0.3158452
yellow black - yellow white 0.1911260 0.1200930 0.95 -0.0442519 0.4265040 1.5914835 Inf 0.2230016
yellow black - dark white -0.3334788 0.1213681 0.95 -0.5713559 -0.0956016 -2.7476631 Inf 0.0308683
yellow black - light white 0.1342266 0.1222199 0.95 -0.1053200 0.3737732 1.0982386 Inf 0.3854777
dark black - light black -0.2050936 0.1202239 0.95 -0.4407280 0.0305409 -1.7059304 Inf 0.1863975
dark black - yellow white 0.1555372 0.1172065 0.95 -0.0741833 0.3852576 1.3270359 Inf 0.3158452
dark black - dark white -0.3690676 0.1188217 0.95 -0.6019538 -0.1361814 -3.1060624 Inf 0.0170637
dark black - light white 0.0986378 0.1178699 0.95 -0.1323829 0.3296585 0.8368361 Inf 0.5177375
light black - yellow white 0.3606307 0.1186619 0.95 0.1280577 0.5932037 3.0391459 Inf 0.0170820
light black - dark white -0.1639740 0.1198071 0.95 -0.3987916 0.0708435 -1.3686508 Inf 0.3079952
light black - light white 0.3037313 0.1179508 0.95 0.0725521 0.5349106 2.5750690 Inf 0.0450990
yellow white - dark white -0.5246048 0.1166497 0.95 -0.7532341 -0.2959755 -4.4972651 Inf 0.0001921
yellow white - light white -0.0568994 0.1158959 0.95 -0.2840512 0.1702524 -0.4909526 Inf 0.7013924
dark white - light white 0.4677054 0.1170361 0.95 0.2383188 0.6970919 3.9962482 Inf 0.0007723

Plot

# Estimated means plot

# Generate interaction-style plot for estimated marginal means
dw_plot_e <- emmip(dwell_emoji_int, ~ emoji_color * profile_pic, CIs = TRUE, type = "response")
dw_df_e <- dw_plot_e$data

dw_df_e <- dw_df_e %>%
  mutate(emoji_color = str_to_title(emoji_color),
         profile_pic = str_to_title(profile_pic))

dw_df_e$profile_pic <- factor(dw_df_e$profile_pic, levels = c("Neutral",
                                                              "Black",
                                                              "White"))

dwell_emoji_pploto <-
  ggplot(dw_df_e, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(dw_df_e$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Profile Picture\n", y = "Estimated Dwell Time on Emojis' AOI (milliseconds)\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    limits = c(400, 1200),
    breaks = seq(400, 1200, 200),
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

dwell_emoji_pploto

# Save plot
# ggsave(filename = "dwell_emoji_pplot.svg", width = 216, height = 131, unit = "mm", dpi = 300)
rm(list = ls(pattern = "^dw_"), anova_model, residuals_anova, dfe_clean, ypred, res, original_range, estimated_range, scaling_factor)

Profile Pictures’ AOI

# General distribution
hist_boxplot(dfp$ia_dwell_time, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(dfp, aes(x = ia_dwell_time)) +
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") +
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

# Remove zero values
sum(!is.na(dfp$ia_dwell_time)) # total of data points
[1] 684
sum(dfp$ia_dwell_time == 0)
[1] 155
dfp$ia_dwell_time[dfp$ia_dwell_time == 0] <- NA
sum(!is.na(dfp$ia_dwell_time)) # total of data points
[1] 529
# Remove outliers
## Identify values less than mean - 2*SD or greater than mean + 2*SD
dw_mean_val <- mean(dfp$ia_dwell_time, na.rm = TRUE)
dw_std_dev <- sd(dfp$ia_dwell_time, na.rm = TRUE)
dw_outliers <- which(dfp$ia_dwell_time < (dw_mean_val - 2 * dw_std_dev) | dfp$ia_dwell_time > (dw_mean_val + 2 * dw_std_dev))
length(dw_outliers)
[1] 19
dfp$ia_dwell_time[dw_outliers] # values in milliseconds
 [1]  7318  3895  4104  5183  7384  4832  4682  4711  4680  3877  6178  4328  3927  3907  5453  4343 18379  5143  4926
## Recode outliers as NA
sum(!is.na(dfp$ia_dwell_time)) # total of data points
[1] 529
dfp$ia_dwell_time[dw_outliers] <- NA
sum(!is.na(dfp$ia_dwell_time)) # total of data points
[1] 510
# ANOVA model fails the assumption of normally distributed residuals
anova_model <- 
  aov(ia_dwell_time ~ profile_pic * emoji_color + emoji_hand_type + texting_usage_s + Error(id),
      data = dfp)
residuals_anova <- anova_model$Within$residuals
qqPlot(residuals_anova)

496 205 
494 203 

Model

# Linear Mixed-Effects Model is not a good fit
dw_lmer <- 
  lmer(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
       data = dfp)
check_predictions(dw_lmer)

dw_check_lmer <- simulateResiduals(dw_lmer, plot = T)
plot(dw_check_lmer)

# Generalized Linear Mixed-Effects Model

## Base model without interaction
dwell_profile_base <- 
  glmmTMB(ia_dwell_time ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = Gamma(link = "log"), 
          data = dfp)

## Check effects
Anova(dwell_profile_base, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_dwell_time
                 Chisq Df Pr(>Chisq)  
emoji_color     7.2892  2    0.02613 *
profile_pic     5.7545  2    0.05629 .
emoji_hand_type 1.5242  2    0.46667  
texting_usage_s 2.5030  1    0.11363  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Model with interaction
dwell_profile_int <- 
  glmmTMB(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = Gamma(link = "log"), 
          data = dfp)

## Check effects
Anova(dwell_profile_int, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: ia_dwell_time
                            Chisq Df           Pr(>Chisq)    
(Intercept)             3416.5173  1 < 0.0000000000000002 ***
emoji_color                6.7784  2              0.03374 *  
profile_pic                5.7635  2              0.05604 .  
emoji_hand_type            0.6591  2              0.71924    
texting_usage_s            1.9838  1              0.15899    
emoji_color:profile_pic   12.6967  4              0.01286 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Compare models
anova(dwell_profile_base, dwell_profile_int)
Data: dfp
Models:
dwell_profile_base: ia_dwell_time ~ 1 + emoji_color + profile_pic + emoji_hand_type + , zi=~0, disp=~1
dwell_profile_base:     texting_usage_s + (1 | id), zi=~0, disp=~1
dwell_profile_int: ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dwell_profile_int:     texting_usage_s + (1 | id), zi=~0, disp=~1
                   Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)  
dwell_profile_base 10 7957.4 7999.7 -3968.7   7937.4                           
dwell_profile_int  14 7952.7 8011.9 -3962.3   7924.7 12.694      4    0.01287 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
tab_model(dwell_profile_int, 
        # file = "dwell_profile_model_int.doc",
          show.aic = T, 
          show.se = T, 
          show.stat = T, 
          transform = NULL
          )
  ia dwell time
Predictors Estimates std. Error CI Statistic p
(Intercept) 6.58 0.11 6.36 – 6.80 58.45 <0.001
emoji color [dark] 0.16 0.14 -0.11 – 0.43 1.17 0.241
emoji color [light] 0.36 0.14 0.09 – 0.64 2.60 0.009
profile pic [black] 0.32 0.13 0.06 – 0.58 2.38 0.017
profile pic [white] 0.19 0.13 -0.06 – 0.44 1.51 0.130
emoji hand type [peace] -0.05 0.08 -0.20 – 0.11 -0.59 0.554
emoji hand type [thumbs] 0.02 0.08 -0.15 – 0.18 0.21 0.831
texting usage s -0.06 0.05 -0.15 – 0.03 -1.41 0.159
emoji color [dark] ×
profile pic [black]
-0.18 0.19 -0.56 – 0.20 -0.93 0.355
emoji color [light] ×
profile pic [black]
-0.33 0.19 -0.70 – 0.04 -1.74 0.081
emoji color [dark] ×
profile pic [white]
0.25 0.18 -0.11 – 0.61 1.35 0.176
emoji color [light] ×
profile pic [white]
-0.30 0.19 -0.67 – 0.06 -1.63 0.103
Random Effects
σ2 0.44
τ00 id 0.08
ICC 0.15
N id 75
Observations 510
Marginal R2 / Conditional R2 0.051 / 0.194
AIC 7952.657

Compare full model

# Compare parsimonious model with full model

## Remove missing values from the dataframe in order to compare models
dfp_clean <- dfp %>% dplyr::select(ia_dwell_time, profile_pic, emoji_color, emoji_hand_type, texting_usage_s, emoji_usage1_s, emoji_usage2_s, skin_color_id_s, identification_level_s, cross1_white_nr_s, cross2_white_nr_s, att_mean_s, inj_white_s, inj_black_s, inj_yellow_s, inj_should_1_s, inj_importance_s, descriptive_norm_s, skin_tone_emoji_id_s, usage_skintone1_s, usage_skintone2_s, politic_left_right_s, id) %>% drop_na()

## Model with all variables
dw_full <- glmmTMB(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id), family = Gamma(link = "log"), data = dfp_clean)

## Parsimonious model with cleaned dataframe
dw_parsimonious <- glmmTMB(ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp_clean)

## Compare models
anova(dw_parsimonious, dw_full)
Data: dfp_clean
Models:
dw_parsimonious: ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_parsimonious:     texting_usage_s + (1 | id), zi=~0, disp=~1
dw_full: ia_dwell_time ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_full:     texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + , zi=~0, disp=~1
dw_full:     identification_level_s + cross1_white_nr_s + cross2_white_nr_s + , zi=~0, disp=~1
dw_full:     att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + , zi=~0, disp=~1
dw_full:     inj_importance_s + inj_importance_s + descriptive_norm_s + , zi=~0, disp=~1
dw_full:     skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + , zi=~0, disp=~1
dw_full:     politic_left_right_s + (1 | id), zi=~0, disp=~1
                Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)
dw_parsimonious 14 5804.9 5859.8 -2888.5   5776.9                         
dw_full         31 5825.9 5947.4 -2881.9   5763.9 13.085     17     0.7305

Quality check

# Check fit
check_predictions(dwell_profile_int)

# Residuals
ypred = predict(dwell_profile_int)
res = residuals(dwell_profile_int, type = 'deviance')
plot(ypred,res)

hist(res)

dw_check <- simulateResiduals(dwell_profile_int, plot = T)
plot(dw_check)

testDispersion(dw_check)


    DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated

data:  simulationOutput
dispersion = 0.91084, p-value = 0.552
alternative hypothesis: two.sided
testOutliers(dw_check)


    DHARMa outlier test based on exact binomial test with approximate expectations

data:  dw_check
outliers at both margin(s) = 1, observations = 510, p-value = 0.2028
alternative hypothesis: true probability of success is not equal to 0.007968127
95 percent confidence interval:
 0.00004964153 0.01087595158
sample estimates:
frequency of outliers (expected: 0.00796812749003984 ) 
                                           0.001960784 

Post-hoc comparisons

# Base model
# Calculate the predicted values
dw_emm_bp <- emmeans(dwell_profile_base, ~ emoji_color)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(dw_emm_bp),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow effect -0.1131701 0.0441868 0.95 -0.1997746 -0.0265656 -2.5611759 Inf 0.0312956
dark effect 0.0859151 0.0443262 0.95 -0.0009627 0.1727928 1.9382463 Inf 0.0788898
light effect 0.0272550 0.0459589 0.95 -0.0628229 0.1173329 0.5930296 Inf 0.5531613
model_parameters(
  emmeans::contrast(dw_emm_bp, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow - dark -0.1990852 0.0756461 0.95 -0.3473489 -0.0508214 -2.6317952 Inf 0.0254805
yellow - light -0.1404251 0.0785148 0.95 -0.2943113 0.0134611 -1.7885169 Inf 0.1105390
dark - light 0.0586601 0.0787502 0.95 -0.0956876 0.2130077 0.7448874 Inf 0.4563398
# Calculate the predicted values
dw_emm_p <- emmeans(dwell_profile_int, ~ emoji_color * profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(dw_emm_p, by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral effect yellow -0.1699875 0.0759650 0.95 -0.3188761 -0.0210988 -2.2377079 Inf 0.0757203
black effect yellow 0.1462540 0.0753830 0.95 -0.0014939 0.2940020 1.9401461 Inf 0.1178144
white effect yellow 0.0237334 0.0725910 0.95 -0.1185423 0.1660092 0.3269474 Inf 0.7437077
neutral effect dark -0.1936388 0.0804584 0.95 -0.3513343 -0.0359433 -2.4066958 Inf 0.0724391
black effect dark -0.0559999 0.0757920 0.95 -0.2045494 0.0925496 -0.7388636 Inf 0.6899847
white effect dark 0.2496387 0.0743314 0.95 0.1039519 0.3953255 3.3584571 Inf 0.0070541
neutral effect light 0.0411452 0.0779377 0.95 -0.1116099 0.1939003 0.5279245 Inf 0.7437077
black effect light 0.0286043 0.0738048 0.95 -0.1160504 0.1732591 0.3875673 Inf 0.7437077
white effect light -0.0697496 0.0754668 0.95 -0.2176618 0.0781627 -0.9242412 Inf 0.6396494
model_parameters(
  emmeans::contrast(dw_emm_p, by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral -0.1753698 0.0783641 0.95 -0.3289606 -0.0217790 -2.2378844 Inf 0.0599093
dark effect neutral -0.0126405 0.0841180 0.95 -0.1775087 0.1522276 -0.1502717 Inf 0.9362976
light effect neutral 0.1880104 0.0845262 0.95 0.0223420 0.3536787 2.2242842 Inf 0.0599093
yellow effect black -0.0062415 0.0780926 0.95 -0.1593001 0.1468171 -0.0799242 Inf 0.9362976
dark effect black -0.0221148 0.0722205 0.95 -0.1636643 0.1194347 -0.3062127 Inf 0.9362976
light effect black 0.0283563 0.0755915 0.95 -0.1198003 0.1765129 0.3751256 Inf 0.9362976
yellow effect white -0.1570168 0.0708255 0.95 -0.2958323 -0.0182013 -2.2169521 Inf 0.0599093
dark effect white 0.2552691 0.0716448 0.95 0.1148479 0.3956902 3.5629834 Inf 0.0033000
light effect white -0.0982523 0.0713869 0.95 -0.2381680 0.0416634 -1.3763353 Inf 0.3036921
model_parameters(
  emmeans::contrast(dw_emm_p, interaction = TRUE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
emoji_color_eff profile_pic_eff Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral effect -0.0624938 0.0625494 0.95 -0.1850883 0.0601008 -0.9991110 Inf 0.4085240
dark effect neutral effect -0.0861451 0.0653674 0.95 -0.2142628 0.0419726 -1.3178612 Inf 0.2813252
light effect neutral effect 0.1486389 0.0644843 0.95 0.0222519 0.2750259 2.3050387 Inf 0.0792974
yellow effect black effect 0.1066345 0.0631829 0.95 -0.0172016 0.2304707 1.6877125 Inf 0.2057995
dark effect black effect -0.0956194 0.0608659 0.95 -0.2149144 0.0236756 -1.5709837 Inf 0.2091356
light effect black effect -0.0110152 0.0605518 0.95 -0.1296946 0.1076643 -0.1819128 Inf 0.8556512
yellow effect white effect -0.0441408 0.0603712 0.95 -0.1624661 0.0741846 -0.7311563 Inf 0.5227691
dark effect white effect 0.1817645 0.0599458 0.95 0.0642728 0.2992562 3.0321455 Inf 0.0218540
light effect white effect -0.1376238 0.0619983 0.95 -0.2591382 -0.0161093 -2.2197984 Inf 0.0792974
model_parameters(
  emmeans::contrast(dw_emm_p, method = "pairwise", by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow - dark neutral -0.1627293 0.1388843 0.95 -0.4349375 0.1094789 -1.1716896 Inf 0.4343791
yellow - light neutral -0.3633802 0.1396259 0.95 -0.6370420 -0.0897184 -2.6025262 Inf 0.0277619
dark - light neutral -0.2006509 0.1493322 0.95 -0.4933366 0.0920348 -1.3436550 Inf 0.4028850
yellow - dark black 0.0158733 0.1300554 0.95 -0.2390306 0.2707773 0.1220506 Inf 0.9028590
yellow - light black -0.0345978 0.1356807 0.95 -0.3005270 0.2313314 -0.2549942 Inf 0.8985685
dark - light black -0.0504711 0.1255440 0.95 -0.2965328 0.1955905 -0.4020195 Inf 0.8841467
yellow - dark white -0.4122859 0.1232979 0.95 -0.6539453 -0.1706265 -3.3438200 Inf 0.0074370
yellow - light white -0.0587645 0.1228483 0.95 -0.2995428 0.1820138 -0.4783500 Inf 0.8841467
dark - light white 0.3535214 0.1242653 0.95 0.1099659 0.5970769 2.8448922 Inf 0.0199919
model_parameters(
  emmeans::contrast(dw_emm_p, method = "pairwise", by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral - black yellow -0.3162415 0.1328047 0.95 -0.5765340 -0.0559490 -2.3812516 Inf 0.0517618
neutral - white yellow -0.1937209 0.1280534 0.95 -0.4447010 0.0572591 -1.5128135 Inf 0.2932358
black - white yellow 0.1225206 0.1270174 0.95 -0.1264289 0.3714701 0.9645969 Inf 0.4948017
neutral - black dark -0.1376389 0.1375165 0.95 -0.4071663 0.1318885 -1.0008901 Inf 0.4948017
neutral - white dark -0.4432775 0.1351036 0.95 -0.7080757 -0.1784793 -3.2810194 Inf 0.0093089
black - white dark -0.3056386 0.1267501 0.95 -0.5540643 -0.0572129 -2.4113476 Inf 0.0517618
neutral - black light 0.0125409 0.1317104 0.95 -0.2456067 0.2706885 0.0952157 Inf 0.9241435
neutral - white light 0.1108948 0.1345062 0.95 -0.1527325 0.3745220 0.8244586 Inf 0.4948017
black - white light 0.0983539 0.1273204 0.95 -0.1511896 0.3478973 0.7724909 Inf 0.4948017
model_parameters(
  emmeans::contrast(dw_emm_p, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow neutral - dark neutral -0.1627293 0.1388843 0.95 -0.4349375 0.1094789 -1.1716896 Inf 0.4572411
yellow neutral - light neutral -0.3633802 0.1396259 0.95 -0.6370420 -0.0897184 -2.6025262 Inf 0.0555238
yellow neutral - yellow black -0.3162415 0.1328047 0.95 -0.5765340 -0.0559490 -2.3812516 Inf 0.0776427
yellow neutral - dark black -0.3003682 0.1309712 0.95 -0.5570670 -0.0436693 -2.2933909 Inf 0.0869115
yellow neutral - light black -0.3508393 0.1325533 0.95 -0.6106389 -0.0910396 -2.6467794 Inf 0.0555238
yellow neutral - yellow white -0.1937209 0.1280534 0.95 -0.4447010 0.0572591 -1.5128135 Inf 0.3351267
yellow neutral - dark white -0.6060068 0.1309398 0.95 -0.8626440 -0.3493696 -4.6281347 Inf 0.0001328
yellow neutral - light white -0.2524854 0.1302451 0.95 -0.5077611 0.0027903 -1.9385404 Inf 0.1576720
dark neutral - light neutral -0.2006509 0.1493322 0.95 -0.4933366 0.0920348 -1.3436550 Inf 0.4076826
dark neutral - yellow black -0.1535122 0.1354678 0.95 -0.4190243 0.1119998 -1.1332007 Inf 0.4628339
dark neutral - dark black -0.1376389 0.1375165 0.95 -0.4071663 0.1318885 -1.0008901 Inf 0.5432228
dark neutral - light black -0.1881100 0.1418833 0.95 -0.4661962 0.0899761 -1.3258080 Inf 0.4076826
dark neutral - yellow white -0.0309916 0.1342894 0.95 -0.2941940 0.2322107 -0.2307825 Inf 0.8655711
dark neutral - dark white -0.4432775 0.1351036 0.95 -0.7080757 -0.1784793 -3.2810194 Inf 0.0124119
dark neutral - light white -0.0897561 0.1357016 0.95 -0.3557264 0.1762141 -0.6614229 Inf 0.7038570
light neutral - yellow black 0.0471387 0.1405010 0.95 -0.2282381 0.3225155 0.3355044 Inf 0.8294002
light neutral - dark black 0.0630120 0.1342334 0.95 -0.2000806 0.3261046 0.4694214 Inf 0.7929539
light neutral - light black 0.0125409 0.1317104 0.95 -0.2456067 0.2706885 0.0952157 Inf 0.9241435
light neutral - yellow white 0.1696593 0.1312317 0.95 -0.0875500 0.4268686 1.2928228 Inf 0.4076826
light neutral - dark white -0.2426266 0.1343978 0.95 -0.5060414 0.0207882 -1.8052873 Inf 0.1966977
light neutral - light white 0.1108948 0.1345062 0.95 -0.1527325 0.3745220 0.8244586 Inf 0.6145185
yellow black - dark black 0.0158733 0.1300554 0.95 -0.2390306 0.2707773 0.1220506 Inf 0.9241435
yellow black - light black -0.0345978 0.1356807 0.95 -0.3005270 0.2313314 -0.2549942 Inf 0.8655711
yellow black - yellow white 0.1225206 0.1270174 0.95 -0.1264289 0.3714701 0.9645969 Inf 0.5477674
yellow black - dark white -0.2897653 0.1285070 0.95 -0.5416343 -0.0378963 -2.2548607 Inf 0.0869115
yellow black - light white 0.0637561 0.1281887 0.95 -0.1874891 0.3150013 0.4973613 Inf 0.7929539
dark black - light black -0.0504711 0.1255440 0.95 -0.2965328 0.1955905 -0.4020195 Inf 0.8170886
dark black - yellow white 0.1066473 0.1236734 0.95 -0.1357481 0.3490426 0.8623300 Inf 0.6080963
dark black - dark white -0.3056386 0.1267501 0.95 -0.5540643 -0.0572129 -2.4113476 Inf 0.0776427
dark black - light white 0.0478828 0.1258549 0.95 -0.1987884 0.2945539 0.3804599 Inf 0.8170886
light black - yellow white 0.1571184 0.1236487 0.95 -0.0852287 0.3994654 1.2706834 Inf 0.4076826
light black - dark white -0.2551675 0.1289542 0.95 -0.5079131 -0.0024220 -1.9787455 Inf 0.1565826
light black - light white 0.0983539 0.1273204 0.95 -0.1511896 0.3478973 0.7724909 Inf 0.6333462
yellow white - dark white -0.4122859 0.1232979 0.95 -0.6539453 -0.1706265 -3.3438200 Inf 0.0124119
yellow white - light white -0.0587645 0.1228483 0.95 -0.2995428 0.1820138 -0.4783500 Inf 0.7929539
dark white - light white 0.3535214 0.1242653 0.95 0.1099659 0.5970769 2.8448922 Inf 0.0399838

Plot

# Estimated means plot

# Generate interaction-style plot for estimated marginal means
dw_plot_p <- emmip(dwell_profile_int, ~ emoji_color * profile_pic, CIs = TRUE, type = "response")
dw_df_p <- dw_plot_p$data

dw_df_p <- dw_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color),
         profile_pic = str_to_title(profile_pic))

dw_df_p$profile_pic <- factor(dw_df_p$profile_pic, levels = c("Neutral",
                                                              "Black",
                                                              "White"))
dwell_profile_pploto <-
  ggplot(dw_df_p, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(dw_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Profile Picture\n", y = "Estimated Dwell Time on Profiles' AOI (milliseconds)\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    limits = c(500, 1600),
    breaks = seq(500, 1600, 200),
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

dwell_profile_pploto

# Save plot
# ggsave(filename = "dwell_profile_pplot.svg", width = 216, height = 131, unit = "mm", dpi = 300)
rm(list = ls(pattern = "^dw_"), anova_model, residuals_anova, dfp_clean, ypred, res, original_range, estimated_range, scaling_factor)

Emojis and Profile Pictures’ AOI compared

# Reduce the variables
dfe_a <-
  dfe %>% dplyr::select(
    id,
    condition,
    ia_dwell_time,
    emoji_color,
    emoji_hand_type,
    texting_usage_s,
    profile_pic
  ) %>% rename(emoji_aoi = ia_dwell_time)

dfp_a <-
  dfp %>% dplyr::select(
    id,
    condition,
    ia_dwell_time,
    emoji_color,
    emoji_hand_type,
    texting_usage_s,
    profile_pic
  ) %>% rename(profile_aoi = ia_dwell_time)

# Merge the datasets
dfg <-
  merge(
    dfe_a,
    dfp_a,
    by = c(
      "id",
      "condition",
      "emoji_color",
      "profile_pic",
      "emoji_hand_type",
      "texting_usage_s"
    ),
    all = TRUE
  )

# Reshape data
long_dfg <- dfg %>%
  gather(key = "AOI", value = "ia_dwell_time", emoji_aoi, profile_aoi)

# Model

dwell_comp1 <- 
  glmmTMB(ia_dwell_time ~ 1 + AOI + emoji_color + profile_pic + 
            emoji_hand_type + texting_usage_s + (1|id),
          family = Gamma(link = "log"), 
          data = long_dfg)
Anova(dwell_comp1, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_dwell_time
                  Chisq Df          Pr(>Chisq)    
AOI             57.9656  1 0.00000000000002667 ***
emoji_color     19.6871  2 0.00005308921516700 ***
profile_pic      4.0023  2             0.13518    
emoji_hand_type  0.6330  2             0.72870    
texting_usage_s  6.3475  1             0.01175 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
dwell_comp2 <- 
  glmmTMB(ia_dwell_time ~ 1 + AOI * emoji_color * profile_pic + 
            emoji_hand_type + texting_usage_s + (1|id),
          family = Gamma(link = "log"), 
          data = long_dfg)
Anova(dwell_comp2, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: ia_dwell_time
                                Chisq Df            Pr(>Chisq)    
(Intercept)                 4878.2057  1 < 0.00000000000000022 ***
AOI                            3.7319  1             0.0533816 .  
emoji_color                    7.7403  2             0.0208549 *  
profile_pic                    2.7149  2             0.2573140    
emoji_hand_type                0.4316  2             0.8058934    
texting_usage_s                5.8898  1             0.0152289 *  
AOI:emoji_color                0.5093  2             0.7751820    
AOI:profile_pic                1.4886  2             0.4750628    
emoji_color:profile_pic       20.0124  4             0.0004966 ***
AOI:emoji_color:profile_pic    2.0888  4             0.7194354    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
tab_model(dwell_comp1,           
          show.aic = T, 
          show.se = T, 
          show.stat = T, 
          transform = NULL
          )
  ia dwell time
Predictors Estimates std. Error CI Statistic p
(Intercept) 6.40 0.06 6.27 – 6.53 99.79 <0.001
AOI [profile_aoi] 0.32 0.04 0.24 – 0.40 7.61 <0.001
emoji color [dark] 0.23 0.05 0.13 – 0.33 4.39 <0.001
emoji color [light] 0.14 0.05 0.04 – 0.25 2.64 0.008
profile pic [black] 0.10 0.05 -0.01 – 0.20 1.86 0.063
profile pic [white] 0.08 0.05 -0.02 – 0.18 1.59 0.111
emoji hand type [peace] -0.01 0.05 -0.11 – 0.09 -0.28 0.781
emoji hand type [thumbs] -0.04 0.05 -0.15 – 0.06 -0.79 0.431
texting usage s -0.08 0.03 -0.14 – -0.02 -2.52 0.012
Random Effects
σ2 0.46
τ00 id 0.04
ICC 0.09
N id 76
Observations 1100
Marginal R2 / Conditional R2 0.079 / 0.160
AIC 16746.220
# Medians
long_dfg %>% group_by(AOI, emoji_color) %>% summarise(median = median(ia_dwell_time, na.rm=T))
# A tibble: 6 × 3
# Groups:   AOI [2]
  AOI         emoji_color median
  <chr>       <fct>        <dbl>
1 emoji_aoi   yellow        464.
2 emoji_aoi   dark          613 
3 emoji_aoi   light         624 
4 profile_aoi yellow        734 
5 profile_aoi dark          924 
6 profile_aoi light         834.
# Plot
ggplot(long_dfg, aes(x = ia_dwell_time, fill = AOI, color = AOI, alpha = AOI)) +
  geom_density(adjust = 1.5, size = 0.75) +
  scale_fill_manual(values = c("lightpink", "darkorange"),
                    labels = c("Profile_AOI", "Emoji_AOI")) +
  scale_color_manual(values = c("lightpink", "darkorange"),
                     labels = c("Profile_AOI", "Emoji_AOI")) +
  scale_alpha_manual(values = c(0.5, 0.5)) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free") +
  labs(title = "Density Plots of AOI by Emoji Color and Profile Pic",
       x = "Dwell Time",
       y = "Density",
       fill = "AOI",
       color = "AOI") +
  theme_minimal() +
  theme(legend.position = "right")

emmip(dwell_comp1, AOI ~ emoji_color * profile_pic, type = "response") + coord_flip() + theme_test()

# only neutral profile pictures and yellow emoji
long_dfgn <- long_dfg %>% dplyr::filter(emoji_color=="yellow", profile_pic=="neutral")

dwell_comp3 <- 
  glmmTMB(ia_dwell_time ~ 1 + AOI + 
            emoji_hand_type + texting_usage_s + (1|id),
          family = Gamma(link = "log"), 
          data = long_dfgn)
Anova(dwell_comp3, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: ia_dwell_time
                    Chisq Df           Pr(>Chisq)    
(Intercept)     2083.0519  1 < 0.0000000000000002 ***
AOI                3.4450  1              0.06344 .  
emoji_hand_type    0.0615  2              0.96973    
texting_usage_s    5.9216  1              0.01496 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Supplementary Analysis

Revisit Count to Emojis’ and Profile Pictures’ AOI

Emojis’ AOI

# General distribution
hist_boxplot(dfe$ia_run_count, col = "lightblue", freq = T, density = F)

table(dfe$ia_run_count)

  0   1   2   3   4   5   6   7   8   9  10  11  14  32 
 77 225 179 101  58  24  11   3   1   1   1   1   1   1 
# Distribution by condition
ggplot(dfe, aes(x = ia_run_count)) +
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") +
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

# Remove outliers
## Identify values less than mean - 2*SD or greater than mean + 2*SD
re_mean_val <- mean(dfe$ia_run_count, na.rm = TRUE)
re_std_dev <- sd(dfe$ia_run_count, na.rm = TRUE)
re_outliers <- which(dfe$ia_run_count < (re_mean_val - 2 * re_std_dev) | dfe$ia_run_count > (re_mean_val + 2 * re_std_dev))
length(re_outliers)
[1] 20
dfe$ia_run_count[re_outliers]
 [1]  7  6 14  6  6  6  6  9  6  6  8  6  6  6  7  6 10 32 11  7
## Recode outliers as NA
sum(!is.na(dfe$ia_run_count)) # total of data points
[1] 684
dfe$ia_run_count[re_outliers] <- NA
sum(!is.na(dfe$ia_run_count)) # total of data points
[1] 664
# ANOVA model fails the assumption of normally distributed residuals
anova_model <- 
  aov(ia_run_count ~ profile_pic * emoji_color + emoji_hand_type + texting_usage_s + Error(id),
      data = dfe)
residuals_anova <- anova_model$Within$residuals
qqPlot(residuals_anova)

123  98 
121  96 

Model

# Linear Mixed-Effects Model is not a good fit
re_lmer <- 
  lmer(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
       data = dfe)
check_predictions(re_lmer)

re_check_lmer <- simulateResiduals(re_lmer, plot = T)
plot(re_check_lmer)

# Find the best fit
dist <- fitDist(ia_run_count, data = dfe, type="counts")
dist$fits
      LG     ZIPF      ZAP    ZANBI    ZAPIG      DPO    ZABNB       PO     NBII      GPO      NBI      ZIP     ZIP2      PIG      NBF    ZINBI      DEL    ZIPIG      BNB    ZIBNB    ZINBF    ZINBF     ZALG     GEOM    GEOMo   WARING   ZAZIPF     YULE 
1805.439 2001.847 2133.784 2135.784 2135.784 2136.784 2137.784 2144.061 2146.061 2146.061 2146.061 2146.061 2146.061 2146.061 2148.061 2148.061 2148.061 2148.061 2148.063 2150.061 2150.061 2150.061 2283.932 2462.776 2462.776 2464.776 2480.340 2983.718 
histDist(ia_run_count, data = dfe, family = PO())


Family:  c("PO", "Poisson") 
Fitting method: "nlminb" 

Call:  gamlssML(formula = ia_run_count, family = "PO", data = dfe) 

Mu Coefficients:
[1]  0.623

 Degrees of Freedom for the fit: 1 Residual Deg. of Freedom   663 
Global Deviance:     2142.06 
            AIC:     2144.06 
            SBC:     2148.56 
re_m0 <- 
  glmer(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id), 
        family = poisson, 
        data = dfe)

re_m1 <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"), 
          data = dfe)

re_m2 <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = compois(link = "log"), 
          data = dfe)

re_m3 <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = nbinom2(link = "log"), 
          data = dfe)

re_m4 <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = nbinom1(link = "log"), 
          data = dfe)

compare_performance(re_m0, re_m1, re_m2, re_m3, re_m4, rank=T) # re_m1 with is the best model
# Comparison of Model Performance Indices

Name  |    Model | R2 (cond.) | R2 (marg.) |   ICC |  RMSE |     Sigma | Performance-Score
------------------------------------------------------------------------------------------
re_m1 |  glmmTMB |      0.152 |      0.052 | 0.106 | 1.154 |     0.764 |            98.14%
re_m2 |  glmmTMB |      0.086 |      0.029 | 0.059 | 1.151 |     0.676 |            41.10%
re_m4 |  glmmTMB |      0.098 |      0.044 | 0.056 | 1.178 | 3.470e-09 |            37.15%
re_m0 | glmerMod |      0.098 |      0.044 | 0.056 | 1.178 |     1.000 |            37.15%
re_m3 |  glmmTMB |      0.098 |      0.044 | 0.056 | 1.178 | 9.544e+06 |            17.16%
# Generalized Poisson Mixed-Effects Model

## Base model without interaction
revisit_emoji_base <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"), 
          data = dfe)

## Check effects
Anova(revisit_emoji_base, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_run_count
                  Chisq Df Pr(>Chisq)    
emoji_color     17.5865  2  0.0001518 ***
profile_pic      0.1353  2  0.9346088    
emoji_hand_type  1.0130  2  0.6025871    
texting_usage_s  1.0956  1  0.2952353    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Model with interaction
revisit_emoji_int <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"), 
          data = dfe)

## Check effects
Anova(revisit_emoji_int, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: ia_run_count
                          Chisq Df   Pr(>Chisq)    
(Intercept)             27.7891  1 0.0000001353 ***
emoji_color              5.9308  2      0.05154 .  
profile_pic              0.8494  2      0.65396    
emoji_hand_type          0.6039  2      0.73939    
texting_usage_s          0.9456  1      0.33084    
emoji_color:profile_pic 11.7858  4      0.01902 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Compare models
anova(revisit_emoji_base, revisit_emoji_int)
Data: dfe
Models:
revisit_emoji_base: ia_run_count ~ 1 + emoji_color + profile_pic + emoji_hand_type + , zi=~0, disp=~1
revisit_emoji_base:     texting_usage_s + (1 | id), zi=~0, disp=~1
revisit_emoji_int: ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
revisit_emoji_int:     texting_usage_s + (1 | id), zi=~0, disp=~1
                   Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)  
revisit_emoji_base 10 2122.3 2167.3 -1051.1   2102.3                           
revisit_emoji_int  14 2118.5 2181.5 -1045.3   2090.5 11.747      4    0.01934 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
tab_model(revisit_emoji_int,
        # file = "revisit_emoji_int.doc",
          show.aic = T, 
          show.se = T, 
          show.stat = T, 
          transform = NULL,
          string.stat = "z",
          string.se = "SE",
          string.ci = "95% CI",
          string.est = "Log-Mean"
          )
  ia run count
Predictors Log-Mean SE 95% CI z p
(Intercept) 0.48 0.09 0.30 – 0.66 5.27 <0.001
emoji color [dark] 0.24 0.11 0.03 – 0.46 2.21 0.027
emoji color [light] 0.21 0.11 -0.00 – 0.43 1.96 0.051
profile pic [black] 0.03 0.11 -0.19 – 0.25 0.25 0.801
profile pic [white] -0.07 0.11 -0.30 – 0.15 -0.65 0.516
emoji hand type [peace] -0.01 0.06 -0.13 – 0.11 -0.16 0.876
emoji hand type [thumbs] -0.05 0.07 -0.19 – 0.08 -0.75 0.456
texting usage s -0.03 0.03 -0.10 – 0.03 -0.97 0.331
emoji color [dark] ×
profile pic [black]
-0.19 0.16 -0.50 – 0.12 -1.17 0.240
emoji color [light] ×
profile pic [black]
0.04 0.15 -0.27 – 0.34 0.23 0.819
emoji color [dark] ×
profile pic [white]
0.21 0.15 -0.09 – 0.51 1.35 0.177
emoji color [light] ×
profile pic [white]
-0.04 0.15 -0.34 – 0.27 -0.24 0.809
Random Effects
σ2 0.35
τ00 id 0.04
ICC 0.11
N id 76
Observations 664
Marginal R2 / Conditional R2 0.052 / 0.152
AIC 2118.534

Compare full model

# Compare parsimonious model with full model

## Remove missing values from the dataframe in order to compare models
dfe_clean <- dfe %>% dplyr::select(ia_run_count, profile_pic, emoji_color, emoji_hand_type, texting_usage_s, emoji_usage1_s, emoji_usage2_s, skin_color_id_s, identification_level_s, cross1_white_nr_s, cross2_white_nr_s, att_mean_s, inj_white_s, inj_black_s, inj_yellow_s, inj_should_1_s, inj_importance_s, descriptive_norm_s, skin_tone_emoji_id_s, usage_skintone1_s, usage_skintone2_s, politic_left_right_s, id) %>% drop_na()

## Model with all variables
dw_full <- glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id), family = genpois(link = "log"), data = dfe_clean)

## Parsimonious model with cleaned dataframe
dw_parsimonious <- glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = genpois(link = "log"), 
                   data = dfe_clean)

## Compare models
anova(dw_parsimonious, dw_full)
Data: dfe_clean
Models:
dw_parsimonious: ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_parsimonious:     texting_usage_s + (1 | id), zi=~0, disp=~1
dw_full: ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_full:     texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + , zi=~0, disp=~1
dw_full:     identification_level_s + cross1_white_nr_s + cross2_white_nr_s + , zi=~0, disp=~1
dw_full:     att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + , zi=~0, disp=~1
dw_full:     inj_importance_s + inj_importance_s + descriptive_norm_s + , zi=~0, disp=~1
dw_full:     skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + , zi=~0, disp=~1
dw_full:     politic_left_right_s + (1 | id), zi=~0, disp=~1
                Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)
dw_parsimonious 14 1553.0 1611.5 -762.49   1525.0                         
dw_full         31 1570.8 1700.3 -754.38   1508.8 16.215     17     0.5086

Quality check

# Check fit
check_predictions(revisit_emoji_int)

re_check <- simulateResiduals(revisit_emoji_int, plot = T)
plot(re_check)

Post-hoc comparisons

# Base model
# Calculate the predicted values
re_emm_be <- emmeans(revisit_emoji_base, ~ emoji_color)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(re_emm_be),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow effect -0.1536463 0.0375513 0.95 -0.2272456 -0.0800471 -4.091634 Inf 0.0001285
dark effect 0.0988271 0.0355121 0.95 0.0292246 0.1684296 2.782912 Inf 0.0080810
light effect 0.0548192 0.0371718 0.95 -0.0180362 0.1276746 1.474753 Inf 0.1402791
model_parameters(
  emmeans::contrast(re_emm_be, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow - dark -0.2524734 0.0629340 0.95 -0.3758217 -0.1291251 -4.0117198 Inf 0.0001808
yellow - light -0.2084656 0.0657464 0.95 -0.3373260 -0.0796051 -3.1707547 Inf 0.0022807
dark - light 0.0440079 0.0622544 0.95 -0.0780084 0.1660242 0.7069044 Inf 0.4796259
# Calculate the predicted values
re_emm_e <- emmeans(revisit_emoji_int, ~ emoji_color * profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(re_emm_e, by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral -0.1516854 0.0626108 0.95 -0.2744003 -0.0289704 -2.4226704 Inf 0.0462207
dark effect neutral 0.0903394 0.0640327 0.95 -0.0351624 0.2158411 1.4108326 Inf 0.2374410
light effect neutral 0.0613460 0.0637533 0.95 -0.0636082 0.1863002 0.9622399 Inf 0.4319089
yellow effect black -0.1015562 0.0664119 0.95 -0.2317212 0.0286088 -1.5291861 Inf 0.2271930
dark effect black -0.0452480 0.0615557 0.95 -0.1658950 0.0753990 -0.7350740 Inf 0.5200812
light effect black 0.1468042 0.0633947 0.95 0.0225530 0.2710554 2.3157192 Inf 0.0462906
yellow effect white -0.2079119 0.0641230 0.95 -0.3335906 -0.0822331 -3.2423925 Inf 0.0053339
dark effect white 0.2402251 0.0582706 0.95 0.1260168 0.3544334 4.1225779 Inf 0.0003372
light effect white -0.0323132 0.0610235 0.95 -0.1519171 0.0872906 -0.5295212 Inf 0.5964439
model_parameters(
  emmeans::contrast(re_emm_e, by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral effect yellow 0.0151186 0.0652879 0.95 -0.1128434 0.1430806 0.2315676 Inf 0.8911989
black effect yellow 0.0436220 0.0656761 0.95 -0.0851008 0.1723449 0.6641994 Inf 0.7598441
white effect yellow -0.0587406 0.0661363 0.95 -0.1883653 0.0708841 -0.8881753 Inf 0.6740036
neutral effect dark 0.0083200 0.0608245 0.95 -0.1108938 0.1275339 0.1367874 Inf 0.8911989
black effect dark -0.1488931 0.0609029 0.95 -0.2682606 -0.0295255 -2.4447596 Inf 0.0652610
white effect dark 0.1405730 0.0575042 0.95 0.0278669 0.2532791 2.4445712 Inf 0.0652610
neutral effect light 0.0158198 0.0599321 0.95 -0.1016450 0.1332846 0.2639619 Inf 0.8911989
black effect light 0.0796523 0.0596396 0.95 -0.0372392 0.1965438 1.3355609 Inf 0.4088089
white effect light -0.0954721 0.0610554 0.95 -0.2151385 0.0241942 -1.5636970 Inf 0.3536662
model_parameters(
  emmeans::contrast(re_emm_e, interaction = TRUE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
emoji_color_eff profile_pic_eff Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral effect 0.0020324 0.0520241 0.95 -0.0999330 0.1039978 0.0390672 Inf 0.9688368
dark effect neutral effect -0.0047661 0.0512711 0.95 -0.1052557 0.0957235 -0.0929589 Inf 0.9688368
light effect neutral effect 0.0027337 0.0502558 0.95 -0.0957659 0.1012333 0.0543951 Inf 0.9688368
yellow effect black effect 0.0521616 0.0531177 0.95 -0.0519471 0.1562703 0.9820014 Inf 0.4891487
dark effect black effect -0.1403535 0.0502003 0.95 -0.2387444 -0.0419626 -2.7958672 Inf 0.0232923
light effect black effect 0.0881919 0.0502193 0.95 -0.0102362 0.1866199 1.7561348 Inf 0.1778971
yellow effect white effect -0.0541940 0.0521493 0.95 -0.1564049 0.0480168 -1.0392086 Inf 0.4891487
dark effect white effect 0.1451196 0.0488053 0.95 0.0494629 0.2407763 2.9734382 Inf 0.0232923
light effect white effect -0.0909256 0.0509096 0.95 -0.1907064 0.0088553 -1.7860215 Inf 0.1778971
model_parameters(
  emmeans::contrast(re_emm_e, method = "pairwise", by = "emoji_color"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast emoji_color Coefficient SE CI CI_low CI_high z df_error p
neutral - black yellow -0.0285035 0.1130386 0.95 -0.2500551 0.1930482 -0.2521569 Inf 0.8009198
neutral - white yellow 0.0738592 0.1138406 0.95 -0.1492644 0.2969827 0.6487945 Inf 0.6015109
black - white yellow 0.1023627 0.1145085 0.95 -0.1220700 0.3267953 0.8939302 Inf 0.5570388
neutral - black dark 0.1572131 0.1072886 0.95 -0.0530688 0.3674949 1.4653284 Inf 0.4284940
neutral - white dark -0.1322530 0.1015063 0.95 -0.3312017 0.0666957 -1.3029042 Inf 0.4333668
black - white dark -0.2894661 0.1016473 0.95 -0.4886912 -0.0902410 -2.8477498 Inf 0.0396266
neutral - black light -0.0638325 0.1028092 0.95 -0.2653348 0.1376698 -0.6208834 Inf 0.6015109
neutral - white light 0.1112919 0.1052728 0.95 -0.0950390 0.3176228 1.0571765 Inf 0.5227759
black - white light 0.1751244 0.1047732 0.95 -0.0302272 0.3804761 1.6714623 Inf 0.4258368
model_parameters(
  emmeans::contrast(re_emm_e, method = "pairwise", by = "profile_pic"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast profile_pic Coefficient SE CI CI_low CI_high z df_error p
yellow - dark neutral -0.2420248 0.1094354 0.95 -0.4565143 -0.0275353 -2.2115762 Inf 0.0670998
yellow - light neutral -0.2130314 0.1089450 0.95 -0.4265597 0.0004970 -1.9554025 Inf 0.0909641
dark - light neutral 0.0289934 0.1113967 0.95 -0.1893401 0.2473269 0.2602716 Inf 0.7946543
yellow - dark black -0.0563082 0.1112673 0.95 -0.2743882 0.1617717 -0.5060625 Inf 0.6894144
yellow - light black -0.2483604 0.1143230 0.95 -0.4724294 -0.0242914 -2.1724448 Inf 0.0670998
dark - light black -0.1920522 0.1058557 0.95 -0.3995255 0.0154211 -1.8142833 Inf 0.1044512
yellow - dark white -0.4481370 0.1062571 0.95 -0.6563971 -0.2398769 -4.2174776 Inf 0.0002223
yellow - light white -0.1755986 0.1107961 0.95 -0.3927551 0.0415578 -1.5848805 Inf 0.1452773
dark - light white 0.2725383 0.1006325 0.95 0.0753022 0.4697744 2.7082533 Inf 0.0304373
model_parameters(
  emmeans::contrast(re_emm_e, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow neutral - dark neutral -0.2420248 0.1094354 0.95 -0.4565143 -0.0275353 -2.2115762 Inf 0.0971855
yellow neutral - light neutral -0.2130314 0.1089450 0.95 -0.4265597 0.0004970 -1.9554025 Inf 0.1399447
yellow neutral - yellow black -0.0285035 0.1130386 0.95 -0.2500551 0.1930482 -0.2521569 Inf 0.8238032
yellow neutral - dark black -0.0848117 0.1098822 0.95 -0.3001769 0.1305535 -0.7718418 Inf 0.5659819
yellow neutral - light black -0.2768639 0.1085272 0.95 -0.4895733 -0.0641545 -2.5511021 Inf 0.0429532
yellow neutral - yellow white 0.0738592 0.1138406 0.95 -0.1492644 0.2969827 0.6487945 Inf 0.6197655
yellow neutral - dark white -0.3742778 0.1040835 0.95 -0.5782778 -0.1702778 -3.5959365 Inf 0.0058181
yellow neutral - light white -0.1017395 0.1088538 0.95 -0.3150889 0.1116100 -0.9346433 Inf 0.4845768
dark neutral - light neutral 0.0289934 0.1113967 0.95 -0.1893401 0.2473269 0.2602716 Inf 0.8238032
dark neutral - yellow black 0.2135213 0.1075654 0.95 0.0026970 0.4243456 1.9850371 Inf 0.1399447
dark neutral - dark black 0.1572131 0.1072886 0.95 -0.0530688 0.3674949 1.4653284 Inf 0.2706278
dark neutral - light black -0.0348391 0.1084365 0.95 -0.2473707 0.1776925 -0.3212859 Inf 0.8159931
dark neutral - yellow white 0.3158840 0.1111104 0.95 0.0981116 0.5336563 2.8429740 Inf 0.0268168
dark neutral - dark white -0.1322530 0.1015063 0.95 -0.3312017 0.0666957 -1.3029042 Inf 0.3151759
dark neutral - light white 0.1402853 0.1066502 0.95 -0.0687453 0.3493159 1.3153776 Inf 0.3151759
light neutral - yellow black 0.1845279 0.1128890 0.95 -0.0367304 0.4057862 1.6345967 Inf 0.2259870
light neutral - dark black 0.1282197 0.1069343 0.95 -0.0813677 0.3378071 1.1990507 Inf 0.3607955
light neutral - light black -0.0638325 0.1028092 0.95 -0.2653348 0.1376698 -0.6208834 Inf 0.6209145
light neutral - yellow white 0.2868906 0.1111394 0.95 0.0690613 0.5047198 2.5813576 Inf 0.0429532
light neutral - dark white -0.1612464 0.1007473 0.95 -0.3587075 0.0362147 -1.6005033 Inf 0.2259870
light neutral - light white 0.1112919 0.1052728 0.95 -0.0950390 0.3176228 1.0571765 Inf 0.4356466
yellow black - dark black -0.0563082 0.1112673 0.95 -0.2743882 0.1617717 -0.5060625 Inf 0.6894144
yellow black - light black -0.2483604 0.1143230 0.95 -0.4724294 -0.0242914 -2.1724448 Inf 0.0975997
yellow black - yellow white 0.1023627 0.1145085 0.95 -0.1220700 0.3267953 0.8939302 Inf 0.4951456
yellow black - dark white -0.3457743 0.1058464 0.95 -0.5532295 -0.1383191 -3.2667541 Inf 0.0130546
yellow black - light white -0.0732360 0.1103092 0.95 -0.2894380 0.1429660 -0.6639157 Inf 0.6197655
dark black - light black -0.1920522 0.1058557 0.95 -0.3995255 0.0154211 -1.8142833 Inf 0.1790592
dark black - yellow white 0.1586709 0.1118569 0.95 -0.0605646 0.3779064 1.4185166 Inf 0.2808720
dark black - dark white -0.2894661 0.1016473 0.95 -0.4886912 -0.0902410 -2.8477498 Inf 0.0268168
dark black - light white -0.0169278 0.1065547 0.95 -0.2257712 0.1919157 -0.1588644 Inf 0.8737757
light black - yellow white 0.3507231 0.1108490 0.95 0.1334630 0.5679831 3.1639714 Inf 0.0140069
light black - dark white -0.0974139 0.0995447 0.95 -0.2925180 0.0976902 -0.9785941 Inf 0.4720040
light black - light white 0.1751244 0.1047732 0.95 -0.0302272 0.3804761 1.6714623 Inf 0.2259870
yellow white - dark white -0.4481370 0.1062571 0.95 -0.6563971 -0.2398769 -4.2174776 Inf 0.0008894
yellow white - light white -0.1755986 0.1107961 0.95 -0.3927551 0.0415578 -1.5848805 Inf 0.2259870
dark white - light white 0.2725383 0.1006325 0.95 0.0753022 0.4697744 2.7082533 Inf 0.0347855

Plot

# Estimated means plot

# Generate interaction-style plot for estimated marginal means
re_plot_e <- emmip(revisit_emoji_int, ~ emoji_color * profile_pic, CIs = TRUE, type = "response")
re_df_e <- re_plot_e$data

re_df_e <- re_df_e %>%
  mutate(emoji_color = str_to_title(emoji_color),
         profile_pic = str_to_title(profile_pic))

re_df_e$profile_pic <- factor(re_df_e$profile_pic, levels = c("Neutral",
                                                              "Black",
                                                              "White"))
revisit_emoji_pploto <-
  ggplot(re_df_e, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(re_df_e$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.6
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Profile Picture\n", y = "Estimated Revisit Count on Emojis' AOI\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    limits = c(1.2, 2.7),
    breaks = seq(1.2, 2.7, 0.2),
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

revisit_emoji_pploto

# Save plot
# ggsave(filename = "revisit_emoji_pplot.svg", width = 216, height = 131, unit = "mm", dpi = 300)
rm(list = ls(pattern = "^re_"), anova_model, residuals_anova, dfe_clean, original_range, estimated_range, scaling_factor)

Profile Pictures’ AOI

# General distribution
hist_boxplot(dfp$ia_run_count, col = "lightblue", freq = T, density = F)

table(dfp$ia_run_count)

  0   1   2   3   4   5   6   7   8   9  10  13  18  19  47 
155 167 152  93  44  27  22  11   2   3   3   2   1   1   1 
# Distribution by condition
ggplot(dfp, aes(x = ia_run_count)) +
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") +
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

# Remove outliers
## Identify values less than mean - 2*SD or greater than mean + 2*SD
re_mean_val <- mean(dfp$ia_run_count, na.rm = TRUE)
re_std_dev <- sd(dfp$ia_run_count, na.rm = TRUE)
re_outliers <- which(dfp$ia_run_count < (re_mean_val - 2 * re_std_dev) | dfp$ia_run_count > (re_mean_val + 2 * re_std_dev))
length(re_outliers)
[1] 13
dfp$ia_run_count[re_outliers]
 [1] 18 10  9  9  9  8 13 10 19 13 47 10  8
## Recode outliers as NA
sum(!is.na(dfp$ia_run_count)) # total of data points
[1] 684
dfp$ia_run_count[re_outliers] <- NA
sum(!is.na(dfp$ia_run_count)) # total of data points
[1] 671
# ANOVA model fails the assumption of normally distributed residuals
anova_model <- 
  aov(ia_run_count ~ profile_pic * emoji_color + emoji_hand_type + texting_usage_s + Error(id),
      data = dfp)
residuals_anova <- anova_model$Within$residuals
qqPlot(residuals_anova)

608 528 
606 526 

Model

# Linear Mixed-Effects Model is not a good fit
re_lmer <- 
  lmer(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1 | id),
       data = dfp)
check_predictions(re_lmer)

re_check_lmer <- simulateResiduals(re_lmer, plot = T)
plot(re_check_lmer)

# Find the best fit
dist <- fitDist(ia_run_count, data = dfp, type = "counts")
dist$fits
      LG     ZIPF      DPO      NBI     NBII    ZANBI    ZINBI      GPO    ZAPIG    ZIPIG      NBF       SI   SICHEL      DEL      BNB    ZINBF    ZINBF ZASICHEL ZISICHEL    ZIBNB    ZABNB      PIG     ZIP2      ZIP      ZAP       PO     GEOM    GEOMo   WARING     ZALG   ZAZIPF     YULE 
1805.459 1994.768 2415.548 2416.857 2416.857 2417.237 2417.237 2417.698 2417.861 2417.861 2418.857 2418.857 2418.857 2418.857 2418.858 2419.237 2419.237 2419.237 2419.237 2419.237 2419.237 2419.855 2435.018 2435.018 2435.018 2480.690 2504.892 2504.892 2506.892 2532.783 2722.092 2900.206 
histDist(ia_run_count, data = dfp, family = PO())


Family:  c("PO", "Poisson") 
Fitting method: "nlminb" 

Call:  gamlssML(formula = ia_run_count, family = "PO", data = dfp) 

Mu Coefficients:
[1]  0.638

 Degrees of Freedom for the fit: 1 Residual Deg. of Freedom   670 
Global Deviance:     2478.69 
            AIC:     2480.69 
            SBC:     2485.2 
# re_m0 <- glmer(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + (1|id), 
#                family = poisson, 
#                data = dfp) # failed to converge

re_m1 <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"), 
          data = dfp)

re_m2 <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = compois(link = "log"), 
          data = dfp)

re_m3 <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = nbinom2(link = "log"), 
          data = dfp)

re_m4 <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = nbinom1(link = "log"), 
          data = dfp)

compare_performance(re_m1, re_m2, re_m3, re_m4, rank = T) # re_m1 is the best model
# Comparison of Model Performance Indices

Name  |   Model | R2 (cond.) | R2 (marg.) |   ICC |  RMSE |  Sigma | AIC weights | AICc weights | BIC weights | Performance-Score
---------------------------------------------------------------------------------------------------------------------------------
re_m1 | glmmTMB |      0.370 |      0.054 | 0.334 | 1.350 |  1.110 |       0.371 |        0.371 |       0.371 |            83.88%
re_m4 | glmmTMB |      0.371 |      0.054 | 0.334 | 1.350 |  0.108 |       0.360 |        0.360 |       0.360 |            82.94%
re_m3 | glmmTMB |      0.385 |      0.057 | 0.348 | 1.349 | 34.652 |       0.120 |        0.120 |       0.120 |            50.00%
re_m2 | glmmTMB |      0.211 |      0.031 | 0.186 | 1.350 |  1.109 |       0.148 |        0.148 |       0.148 |            23.17%
# Generalized Poisson Mixed-Effects Model

## Base model without interaction
revisit_profile_base <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"), 
          data = dfp)

## Check effects
Anova(revisit_profile_base, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_run_count
                  Chisq Df   Pr(>Chisq)    
emoji_color      4.6541  2      0.09758 .  
profile_pic     31.4129  2 0.0000001509 ***
emoji_hand_type  0.3949  2      0.82084    
texting_usage_s  0.4422  1      0.50604    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Model with interaction
revisit_profile_int <- 
  glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"), 
          data = dfp)

## Check effects
Anova(revisit_profile_int, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: ia_run_count
                          Chisq Df Pr(>Chisq)   
(Intercept)              1.6456  1    0.19956   
emoji_color              2.2285  2    0.32816   
profile_pic             13.2305  2    0.00134 **
emoji_hand_type          0.3988  2    0.81923   
texting_usage_s          0.4580  1    0.49857   
emoji_color:profile_pic  5.7129  4    0.22164   
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Compare models
anova(revisit_profile_base, revisit_profile_int)
Data: dfp
Models:
revisit_profile_base: ia_run_count ~ 1 + emoji_color + profile_pic + emoji_hand_type + , zi=~0, disp=~1
revisit_profile_base:     texting_usage_s + (1 | id), zi=~0, disp=~1
revisit_profile_int: ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
revisit_profile_int:     texting_usage_s + (1 | id), zi=~0, disp=~1
                     Df    AIC    BIC  logLik deviance Chisq Chi Df Pr(>Chisq)
revisit_profile_base 10 2301.2 2346.3 -1140.6   2281.2                        
revisit_profile_int  14 2303.5 2366.6 -1137.8   2275.5 5.734      4     0.2199
## Check summary
tab_model(revisit_profile_base, 
        # file = "revisit_profile_base.doc",
          show.se = T, 
          show.obs = T, 
          show.stat = T, 
          show.aic = T, 
          transform = NULL,
          string.stat = "z",
          string.se = "SE",
          string.ci = "95% CI",
          string.est = "Log-Mean"
          )
  ia run count
Predictors Log-Mean SE 95% CI z p
(Intercept) 0.21 0.10 0.01 – 0.42 2.04 0.041
emoji color [dark] 0.15 0.07 0.01 – 0.29 2.06 0.039
emoji color [light] 0.04 0.08 -0.11 – 0.19 0.50 0.617
profile pic [black] 0.37 0.08 0.22 – 0.52 4.85 <0.001
profile pic [white] 0.39 0.08 0.24 – 0.54 5.13 <0.001
emoji hand type [peace] -0.04 0.07 -0.19 – 0.10 -0.60 0.551
emoji hand type [thumbs] -0.01 0.08 -0.16 – 0.14 -0.11 0.913
texting usage s -0.04 0.07 -0.17 – 0.08 -0.67 0.506
Random Effects
σ2 0.51
τ00 id 0.25
ICC 0.33
N id 76
Observations 671
Marginal R2 / Conditional R2 0.049 / 0.364
AIC 2301.225

Compare full model

# Compare parsimonious model with full model

## Remove missing values from the dataframe in order to compare models
dfp_clean <- dfp %>% dplyr::select(ia_run_count, profile_pic, emoji_color, emoji_hand_type, texting_usage_s, emoji_usage1_s, emoji_usage2_s, skin_color_id_s, identification_level_s, cross1_white_nr_s, cross2_white_nr_s, att_mean_s, inj_white_s, inj_black_s, inj_yellow_s, inj_should_1_s, inj_importance_s, descriptive_norm_s, skin_tone_emoji_id_s, usage_skintone1_s, usage_skintone2_s, politic_left_right_s, id) %>% drop_na()

## Model with all variables
dw_full <- glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + identification_level_s + cross1_white_nr_s + cross2_white_nr_s + att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + inj_importance_s + inj_importance_s + descriptive_norm_s + skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + politic_left_right_s + (1 | id), family = genpois(link = "log"), data = dfp_clean)

## Parsimonious model with cleaned dataframe
dw_parsimonious <- glmmTMB(ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = genpois(link = "log"), 
                   data = dfp_clean)

## Compare models
anova(dw_parsimonious, dw_full)
Data: dfp_clean
Models:
dw_parsimonious: ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_parsimonious:     texting_usage_s + (1 | id), zi=~0, disp=~1
dw_full: ia_run_count ~ 1 + emoji_color * profile_pic + emoji_hand_type + , zi=~0, disp=~1
dw_full:     texting_usage_s + emoji_usage1_s + emoji_usage2_s + skin_color_id_s + , zi=~0, disp=~1
dw_full:     identification_level_s + cross1_white_nr_s + cross2_white_nr_s + , zi=~0, disp=~1
dw_full:     att_mean_s + inj_white_s + inj_black_s + inj_yellow_s + inj_should_1_s + , zi=~0, disp=~1
dw_full:     inj_importance_s + inj_importance_s + descriptive_norm_s + , zi=~0, disp=~1
dw_full:     skin_tone_emoji_id_s + usage_skintone1_s + usage_skintone2_s + , zi=~0, disp=~1
dw_full:     politic_left_right_s + (1 | id), zi=~0, disp=~1
                Df    AIC    BIC  logLik deviance  Chisq Chi Df Pr(>Chisq)
dw_parsimonious 14 1661.6 1720.2 -816.79   1633.6                         
dw_full         31 1676.5 1806.2 -807.23   1614.5 19.127     17     0.3213

Quality check

# Check fit
check_predictions(revisit_profile_base)

re_check <- simulateResiduals(revisit_profile_base, plot = T)
plot(re_check)

Post-hoc comparisons

# Calculate the predicted values
re_emm_p <- emmeans(revisit_profile_base, ~ profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(re_emm_p),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
neutral effect -0.2549243 0.0455548 0.95 -0.3442100 -0.1656386 -5.595997 Inf 0.0000001
black effect 0.1171428 0.0414145 0.95 0.0359718 0.1983138 2.828543 Inf 0.0046760
white effect 0.1377815 0.0413212 0.95 0.0567933 0.2187696 3.334399 Inf 0.0012823
model_parameters(
  emmeans::contrast(re_emm_p, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
neutral - black -0.3720671 0.0766378 0.95 -0.5222745 -0.2218598 -4.854876 Inf 0.0000018
neutral - white -0.3927058 0.0764866 0.95 -0.5426167 -0.2427948 -5.134310 Inf 0.0000008
black - white -0.0206386 0.0690651 0.95 -0.1560037 0.1147264 -0.298829 Inf 0.7650705

Plot

# Estimated means plot

# Generate interaction-style plot for estimated marginal means
re_plot_p <- emmip(revisit_profile_base, ~ emoji_color * profile_pic, CIs = TRUE, type = "response")
re_df_p <- re_plot_p$data

re_df_p <- re_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color),
         profile_pic = str_to_title(profile_pic))

re_df_p$profile_pic <- factor(re_df_p$profile_pic, levels = c("Neutral",
                                                              "Black",
                                                              "White"))
revisit_profile_pploto <-
  ggplot(re_df_p, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(re_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Profile Picture\n", y = "Estimated Revisit Count on Profiles' AOI\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    limits = c(1, 2.6),
    breaks = seq(1, 2.6, 0.2),
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

revisit_profile_pploto

# Save plot
# ggsave(filename = "revisit_profile_pplot.svg", width = 216, height = 131, unit = "mm", dpi = 300)
rm(list = ls(pattern = "^re_"), anova_model, residuals_anova, dfp_clean, original_range, estimated_range, scaling_factor)

Emojis and Profile Pictures’ AOI compared

# Reduce the variables
dfe_b <-
  dfe %>% dplyr::select(
    id,
    condition,
    ia_run_count,
    emoji_color,
    emoji_hand_type,
    texting_usage_s,
    profile_pic
  ) %>% rename(emoji_aoi = ia_run_count)

dfp_b <-
  dfp %>% dplyr::select(
    id,
    condition,
    ia_run_count,
    emoji_color,
    emoji_hand_type,
    texting_usage_s,
    profile_pic
  ) %>% rename(profile_aoi = ia_run_count)

# Merge the datasets
dfr <-
  merge(
    dfe_b,
    dfp_b,
    by = c(
      "id",
      "condition",
      "emoji_color",
      "profile_pic",
      "emoji_hand_type",
      "texting_usage_s"
    ),
    all = TRUE
  )

# Reshape data
long_dfr <- dfr %>%
  gather(key = "AOI", value = "ia_run_count", emoji_aoi, profile_aoi)

# Model

revisit_comp1 <- 
  glmmTMB(ia_run_count ~ 1 + AOI + emoji_color + profile_pic + 
            emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"), 
          data = long_dfr)
Anova(revisit_comp1, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_run_count
                  Chisq Df Pr(>Chisq)    
AOI              0.0684  1  0.7936694    
emoji_color     15.5033  2  0.0004300 ***
profile_pic     14.3118  2  0.0007802 ***
emoji_hand_type  0.5755  2  0.7499400    
texting_usage_s  1.0391  1  0.3080311    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
revisit_comp2 <- 
  glmmTMB(ia_run_count ~ 1 + AOI * profile_pic + emoji_color +
            emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"),
          data = long_dfr)
Anova(revisit_comp2, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: ia_run_count
                  Chisq Df        Pr(>Chisq)    
(Intercept)     49.8483  1 0.000000000001661 ***
AOI             14.0660  1         0.0001765 ***
profile_pic      0.3625  2         0.8342143    
emoji_color     15.6668  2         0.0003963 ***
emoji_hand_type  0.5540  2         0.7580560    
texting_usage_s  1.0330  1         0.3094486    
AOI:profile_pic 21.8994  2 0.000017563062712 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
revisit_comp3 <- 
  glmmTMB(ia_run_count ~ 1 + AOI * emoji_color * profile_pic + 
            emoji_hand_type + texting_usage_s + (1|id),
          family = genpois(link = "log"), 
          data = long_dfr)
Anova(revisit_comp3, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: ia_run_count
                              Chisq Df  Pr(>Chisq)    
(Intercept)                 21.5067  1 0.000003526 ***
AOI                          3.0733  1    0.079588 .  
emoji_color                  4.4109  2    0.110201    
profile_pic                  0.4973  2    0.779845    
emoji_hand_type              0.5003  2    0.778665    
texting_usage_s              1.0303  1    0.310088    
AOI:emoji_color              0.7644  2    0.682354    
AOI:profile_pic              9.4732  2    0.008769 ** 
emoji_color:profile_pic      9.2739  4    0.054606 .  
AOI:emoji_color:profile_pic  0.9122  4    0.922797    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Calculate the predicted values
dfr_emm <- emmeans(revisit_comp2, ~ AOI * profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(dfr_emm, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
emoji_aoi neutral - profile_aoi neutral 0.2818688 0.0751556 0.95 0.1345666 0.4291710 3.7504718 Inf 0.0146436
emoji_aoi neutral - emoji_aoi black 0.0420549 0.0705464 0.95 -0.0962136 0.1803234 0.5961308 Inf 0.9999994
emoji_aoi neutral - profile_aoi black -0.0949068 0.0682005 0.95 -0.2285774 0.0387637 -1.3915853 Inf 0.9881947
emoji_aoi neutral - emoji_aoi white 0.0256393 0.0701382 0.95 -0.1118290 0.1631076 0.3655544 Inf 1.0000000
emoji_aoi neutral - profile_aoi white -0.1094085 0.0677690 0.95 -0.2422334 0.0234163 -1.6144326 Inf 0.9559603
profile_aoi neutral - emoji_aoi black -0.2398139 0.0759618 0.95 -0.3886964 -0.0909314 -3.1570306 Inf 0.1006102
profile_aoi neutral - profile_aoi black -0.3767756 0.0734906 0.95 -0.5208145 -0.2327368 -5.1268569 Inf 0.0000301
profile_aoi neutral - emoji_aoi white -0.2562295 0.0756330 0.95 -0.4044675 -0.1079915 -3.3877986 Inf 0.0505452
profile_aoi neutral - profile_aoi white -0.3912773 0.0732652 0.95 -0.5348745 -0.2476801 -5.3405606 Inf 0.0000096
emoji_aoi black - profile_aoi black -0.1369617 0.0690363 0.95 -0.2722705 -0.0016530 -1.9839077 Inf 0.8083032
emoji_aoi black - emoji_aoi white -0.0164156 0.0710813 0.95 -0.1557325 0.1229013 -0.2309411 Inf 1.0000000
emoji_aoi black - profile_aoi white -0.1514634 0.0686714 0.95 -0.2860569 -0.0168700 -2.2056267 Inf 0.6608815
profile_aoi black - emoji_aoi white 0.1205461 0.0686954 0.95 -0.0140943 0.2551866 1.7547932 Inf 0.9157183
profile_aoi black - profile_aoi white -0.0145017 0.0660926 0.95 -0.1440408 0.1150374 -0.2194147 Inf 1.0000000
emoji_aoi white - profile_aoi white -0.1350478 0.0682681 0.95 -0.2688508 -0.0012448 -1.9781986 Inf 0.8116025
# Medians
long_dfr %>% group_by(AOI, profile_pic) %>% summarise(median = median(ia_run_count, na.rm=T))
# A tibble: 6 × 3
# Groups:   AOI [2]
  AOI         profile_pic median
  <chr>       <fct>        <dbl>
1 emoji_aoi   neutral          2
2 emoji_aoi   black            2
3 emoji_aoi   white            2
4 profile_aoi neutral          1
5 profile_aoi black            2
6 profile_aoi white            2
# Plot
ggplot(long_dfr, aes(x = ia_run_count, fill = AOI, color = AOI, alpha = AOI)) +
  geom_density(adjust = 1.5, size = 0.75) +
  scale_fill_manual(values = c("lightpink", "darkorange"),
                    labels = c("Profile_AOI", "Emoji_AOI")) +
  scale_color_manual(values = c("lightpink", "darkorange"),
                     labels = c("Profile_AOI", "Emoji_AOI")) +
  scale_alpha_manual(values = c(0.5, 0.5)) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free") +
  labs(title = "Density Plots of AOI by Emoji Color and Profile Pic",
       x = "Revisit Counts",
       y = "Density",
       fill = "AOI",
       color = "AOI") +
  theme_minimal() +
  theme(legend.position = "right")

emmip(revisit_comp2, AOI ~ emoji_color * profile_pic, type = "response") + coord_flip() + theme_test()

Texting Frequency

Sender’s Competence Ratings

plot_model(sender_competence_base, terms = "texting_usage_s [all]", type = "pred")

Dwell Times over Emoji’s AOI

plot_model(dwell_emoji_base, terms = "texting_usage_s [all]", type = "pred")

Emoji Hand Types

Sender’s Warmth Ratings

# Calculate the predicted values
eh_emm <- emmeans(sender_warmth_base, ~ emoji_hand_type)

model_parameters(
  emmeans::contrast(eh_emm, method = "revpairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
peace - ok -0.1784437 0.1749071 0.95 -0.5212552 0.1643679 -1.020220 Inf 0.3076242
thumbs - ok 1.0310018 0.1848556 0.95 0.6686915 1.3933121 5.577336 Inf 0.0000000
thumbs - peace 1.2094455 0.1873968 0.95 0.8421544 1.5767365 6.453927 Inf 0.0000000
# Estimated means plot
eh_plotv <- emmip(sender_warmth_int, ~ emoji_hand_type, CIs = TRUE, type = "response")
eh_df_pc <- eh_plotv$data

eh_plotb <-
  ggplot(eh_df_pc, aes(
    x = emoji_hand_type,
    y = yvar
  )) +
  geom_hline(
    yintercept = mean(eh_df_pc$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Emoji Hand Types\n", y = "Sender's Warmth Ratings\n") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'none',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    position = "right"
  ) + coord_flip() 

eh_plotb

Relationship Quality Ratings

# Calculate the predicted values
eh_emm <- emmeans(quality_int, ~ emoji_hand_type)

model_parameters(
  emmeans::contrast(eh_emm, method = "revpairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
peace - ok -0.4804147 0.1796659 0.95 -0.8325534 -0.1282759 -2.673933 Inf 0.0074967
thumbs - ok 1.6865731 0.2043966 0.95 1.2859631 2.0871830 8.251473 Inf 0.0000000
thumbs - peace 2.1669877 0.2107783 0.95 1.7538698 2.5801057 10.280885 Inf 0.0000000
# Estimated means plot
eh_plot <- emmip(quality_int, ~ emoji_hand_type, CIs = TRUE, type = "response")
eh_df_p <- eh_plot$data

eh_plota <-
  ggplot(eh_df_p, aes(
    x = emoji_hand_type,
    y = yvar
  )) +
  geom_hline(
    yintercept = mean(eh_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Emoji Hand Types\n", y = "Relationship Quality Ratings\n") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'none',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

eh_plota

rm(list = ls(pattern = "^eh_"))

Emoji Recognition

# Compute participants' performance of emoji recognition
# 1 if participant gave correct answer and 0 if not
dfp <- dfp %>%
  mutate(n.emoji_recognition_result = as.integer(correct_emoji_recognition == emoji_recognition)) %>%
  relocate(n.emoji_recognition_result, .after=rt_emoji_recognition)

# Write variable with the correct emoji
dfp$n.emoji_recognition_correct_item <- with(dfp,
                            case_when(
                              correct_emoji_recognition == 1 ~ emoji_recognition_option1,
                              correct_emoji_recognition == 2 ~ emoji_recognition_option2,
                              correct_emoji_recognition == 3 ~ emoji_recognition_option3,
                              correct_emoji_recognition == 4 ~ emoji_recognition_option4,
                              correct_emoji_recognition == 5 ~ emoji_recognition_option5,
                              TRUE ~ emoji_recognition_option6))

# Write variable with the chosen emoji
dfp$n.emoji_recognition_chosen_item <- with(dfp,
                              case_when(
                                emoji_recognition == 1 ~ emoji_recognition_option1,
                                emoji_recognition == 2 ~ emoji_recognition_option2,
                                emoji_recognition == 3 ~ emoji_recognition_option3,
                                emoji_recognition == 4 ~ emoji_recognition_option4,
                                emoji_recognition == 5 ~ emoji_recognition_option5,
                                TRUE ~ emoji_recognition_option6))

# Mapping of combinations to result type
emoji_mapping <- list(
  "tpeace0.png_tpeace2.png" = "wrong skin tone",
  "tpeace0.png_tpeace4.png" = "wrong skin tone",
  "tpeace2.png_tpeace0.png" = "wrong skin tone",
  "tpeace2.png_tpeace4.png" = "wrong skin tone",
  "tpeace4.png_tpeace0.png" = "wrong skin tone",
  "tpeace4.png_tpeace2.png" = "wrong skin tone",
  "tthumbs0.png_tthumbs2.png" = "wrong skin tone",
  "tthumbs0.png_tthumbs4.png" = "wrong skin tone",
  "tthumbs2.png_tthumbs0.png" = "wrong skin tone",
  "tthumbs2.png_tthumbs4.png" = "wrong skin tone",
  "tthumbs4.png_tthumbs0.png" = "wrong skin tone",
  "tthumbs4.png_tthumbs2.png" = "wrong skin tone",
  "tok0.png_tok2.png" = "wrong skin tone",
  "tok0.png_tok4.png" = "wrong skin tone",
  "tok2.png_tok0.png" = "wrong skin tone",
  "tok2.png_tok4.png" = "wrong skin tone",
  "tok4.png_tok0.png" = "wrong skin tone",
  "tok4.png_tok2.png" = "wrong skin tone",
  "tok0.png_clapping0.png" = "wrong emoji type",
  "tok0.png_raising0.png" = "wrong emoji type",
  "tok2.png_raising2.png" = "wrong emoji type",
  "tok2.png_crossed2.png" = "wrong emoji type",
  "tok4.png_crossed4.png" = "wrong emoji type",
  "tpeace2.png_clapping2.png" = "wrong emoji type",
  "tpeace2.png_crossed2.png" = "wrong emoji type",
  "tpeace2.png_raising2.png" = "wrong emoji type",
  "tthumbs0.png_clapping0.png" = "wrong emoji type",
  "tthumbs0.png_raising0.png" = "wrong emoji type",
  "tthumbs4.png_clapping4.png" = "wrong emoji type",
  "tthumbs4.png_crossed4.png" = "wrong emoji type"
)

# Function to determine recognition result
get_emoji_recognition <- function(correct, result, chosen) {
  if (correct == 1) {
    return(NA)
  } 
  key <- paste(result, chosen, sep="_")
  if (key %in% names(emoji_mapping)) {
    return(emoji_mapping[[key]])
  }
  return("all wrong")
}

# Apply the function to determine emoji recognition result type
dfp$n.emoji_recognition_result_type <- with(dfp, mapply(get_emoji_recognition, n.emoji_recognition_result, n.emoji_recognition_correct_item, n.emoji_recognition_chosen_item))

#relocate new columns
dfp <- dfp %>% 
  relocate(n.emoji_recognition_chosen_item, .after=n.emoji_recognition_result) %>%
  relocate(n.emoji_recognition_correct_item, .after=n.emoji_recognition_chosen_item) %>%
  relocate(n.emoji_recognition_result_type, .after=n.emoji_recognition_correct_item)
# General distribution
table(dfp$n.emoji_recognition_result)

  0   1 
165 519 
dfp %>% 
  distinct(id, .keep_all = TRUE) %>% # Remove duplicates based on id
  summarise(mean_value = mean(n.emoji_recognition_result, na.rm = TRUE))
  mean_value
1  0.7368421
# Distribution by condition
ggplot(dfp, aes(x = n.emoji_recognition_result)) +
  geom_bar() +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

## Run binomial model
em_base <- 
  glmer(n.emoji_recognition_result ~ emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id), 
        data = dfp, 
        family = "binomial")
Anova(em_base, type = "2") 
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: n.emoji_recognition_result
                 Chisq Df Pr(>Chisq)  
emoji_color     1.1109  2    0.57380  
profile_pic     0.5235  2    0.76970  
emoji_hand_type 5.0921  2    0.07839 .
texting_usage_s 0.8851  1    0.34681  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
em_int <- 
  glmer(n.emoji_recognition_result ~ emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id), 
        data = dfp,
        family = "binomial")
Anova(em_int, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: n.emoji_recognition_result
                         Chisq Df Pr(>Chisq)   
(Intercept)             9.7602  1   0.001783 **
emoji_color             3.6596  2   0.160447   
profile_pic             4.1682  2   0.124418   
emoji_hand_type         6.4595  2   0.039568 * 
texting_usage_s         0.8674  1   0.351665   
emoji_color:profile_pic 9.9016  4   0.042117 * 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Check summary
report_table(em_int)
Parameter                                 | Coefficient |         95% CI |     z |     p | Effects | Group | Std. Coef. | Std. Coef. 95% CI |    Fit
----------------------------------------------------------------------------------------------------------------------------------------------------
(Intercept)                               |        0.96 | [ 0.36,  1.56] |  3.12 | 0.002 |   fixed |       |       0.96 |    [ 0.36,  1.56] |       
emoji color [dark]                        |        0.31 | [-0.46,  1.07] |  0.79 | 0.429 |   fixed |       |       0.31 |    [-0.46,  1.07] |       
emoji color [light]                       |        0.83 | [-0.02,  1.68] |  1.91 | 0.056 |   fixed |       |       0.83 |    [-0.02,  1.68] |       
profile pic [black]                       |        0.82 | [ 0.02,  1.63] |  2.02 | 0.043 |   fixed |       |       0.82 |    [ 0.02,  1.62] |       
profile pic [white]                       |        0.44 | [-0.32,  1.21] |  1.14 | 0.255 |   fixed |       |       0.44 |    [-0.32,  1.21] |       
emoji hand type [peace]                   |        0.37 | [-0.10,  0.85] |  1.54 | 0.124 |   fixed |       |       0.37 |    [-0.10,  0.85] |       
emoji hand type [thumbs]                  |       -0.27 | [-0.75,  0.22] | -1.08 | 0.279 |   fixed |       |      -0.27 |    [-0.75,  0.22] |       
texting usage s                           |       -0.11 | [-0.34,  0.12] | -0.93 | 0.352 |   fixed |       |      -0.11 |    [-0.34,  0.12] |       
emoji color [dark] × profile pic [black]  |       -1.09 | [-2.22,  0.04] | -1.89 | 0.059 |   fixed |       |      -1.09 |    [-2.22,  0.04] |       
emoji color [light] × profile pic [black] |       -1.75 | [-2.94, -0.57] | -2.90 | 0.004 |   fixed |       |      -1.75 |    [-2.94, -0.57] |       
emoji color [dark] × profile pic [white]  |       -0.56 | [-1.65,  0.53] | -1.01 | 0.315 |   fixed |       |      -0.56 |    [-1.65,  0.53] |       
emoji color [light] × profile pic [white] |       -1.35 | [-2.49, -0.21] | -2.32 | 0.020 |   fixed |       |      -1.35 |    [-2.50, -0.21] |       
                                          |        0.59 |                |       |       |  random |    id |            |                   |       
                                          |             |                |       |       |         |       |            |                   |       
AIC                                       |             |                |       |       |         |       |            |                   | 758.35
AICc                                      |             |                |       |       |         |       |            |                   | 758.89
BIC                                       |             |                |       |       |         |       |            |                   | 817.21
R2 (conditional)                          |             |                |       |       |         |       |            |                   |   0.13
R2 (marginal)                             |             |                |       |       |         |       |            |                   |   0.04
Sigma                                     |             |                |       |       |         |       |            |                   |   1.00
Log_loss                                  |             |                |       |       |         |       |            |                   |   0.49
# Calculate the predicted values
em_emm <- emmeans(em_int, ~ emoji_color * profile_pic)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(em_emm, interaction = TRUE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
emoji_color_eff profile_pic_eff Coefficient SE CI CI_low CI_high z df_error p
yellow effect neutral effect -0.5278178 0.1897542 0.95 -0.8997292 -0.1559063 -2.7815866 Inf 0.0486845
dark effect neutral effect 0.0208256 0.1956170 0.95 -0.3625767 0.4042279 0.1064612 Inf 0.9152165
light effect neutral effect 0.5069922 0.2059749 0.95 0.1032888 0.9106955 2.4614270 Inf 0.0622735
yellow effect black effect 0.4185766 0.2000962 0.95 0.0263952 0.8107580 2.0918763 Inf 0.1093487
dark effect black effect -0.1197451 0.1858632 0.95 -0.4840302 0.2445401 -0.6442646 Inf 0.6678925
light effect black effect -0.2988315 0.1925765 0.95 -0.6762746 0.0786116 -1.5517545 Inf 0.2716222
yellow effect white effect 0.1092412 0.1901958 0.95 -0.2635357 0.4820181 0.5743618 Inf 0.6678925
dark effect white effect 0.0989195 0.1854134 0.95 -0.2644842 0.4623231 0.5335076 Inf 0.6678925
light effect white effect -0.2081607 0.1913204 0.95 -0.5831417 0.1668204 -1.0880214 Inf 0.4978542
model_parameters(
  emmeans::contrast(em_emm, interaction = TRUE, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
emoji_color_pairwise profile_pic_pairwise Coefficient SE CI CI_low CI_high z df_error p
yellow - dark neutral - black -1.0869650 0.5761083 0.95 -2.2161166 0.0421865 -1.8867373 Inf 0.1775870
yellow - light neutral - black -1.7522180 0.6045049 0.95 -2.9370258 -0.5674102 -2.8986002 Inf 0.0337349
dark - light neutral - black -0.6652530 0.5927992 0.95 -1.8271181 0.4966122 -1.1222231 Inf 0.4575423
yellow - dark neutral - white -0.5589651 0.5560226 0.95 -1.6487495 0.5308192 -1.0052920 Inf 0.4575423
yellow - light neutral - white -1.3522118 0.5829660 0.95 -2.4948042 -0.2096194 -2.3195380 Inf 0.0916465
dark - light neutral - white -0.7932467 0.5992560 0.95 -1.9677668 0.3812735 -1.3237192 Inf 0.4175917
yellow - dark black - white 0.5279999 0.5718800 0.95 -0.5928643 1.6488641 0.9232705 Inf 0.4575423
yellow - light black - white 0.4000062 0.5858016 0.95 -0.7481437 1.5481562 0.6828357 Inf 0.5565495
dark - light black - white -0.1279937 0.5409688 0.95 -1.1882732 0.9322857 -0.2366009 Inf 0.8129664
# Estimated means plot
em_er_plot <- emmip(em_int, ~ emoji_color * profile_pic, CIs = TRUE, type = "response")
em_er_df_p <- em_er_plot$data

em_plota <-
  ggplot(em_er_df_p, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(em_er_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Profile Picture\n", y = "Estimated Emojis Recognition\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
    scale_y_continuous(
    position = "right" 
    ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

em_plota

rm(list = ls(pattern = "^em_"), get_emoji_recognition, emoji_mapping)

Receiver’s Racialized Profile in the Neutral Condition

# Compute index of participant's confident level about receiver's racialized profile
datra$confident_level_r <- datra$receiver_black - datra$receiver_white
# General distribution
hist_boxplot(datra$confident_level_r, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(datra, aes(x = confident_level_r)) + 
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") + 
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

table(datra$confident_level_r)

 -6  -4  -3  -2  -1   0   1   2   3   4   6 
  4  12   5  11   4 179   1   6   2   2   2 
## Transform data so zero, which is the focus, is 1, and non-zero is 0.
datra$confident_level_r_zero <- ifelse(datra$confident_level_r == 0, 1, 0)
table(datra$confident_level_r_zero)

  0   1 
 49 179 
## Run binomial model
receiver_racialized_model_zero <- 
  glmer(confident_level_r_zero ~ emoji_color + emoji_hand_type + texting_usage_s + (1|id), 
        data = datra, 
        family = "binomial")

# Check effects
Anova(receiver_racialized_model_zero)
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: confident_level_r_zero
                 Chisq Df Pr(>Chisq)
emoji_color     0.5334  2     0.7659
emoji_hand_type 0.6917  2     0.7076
texting_usage_s 0.8085  1     0.3686
# Check quality of the model
rr_check <- simulateResiduals(receiver_racialized_model_zero, plot = T)
plot(rr_check)

# Transform data so only non-zero are included
datra$confident_level_r_nonzero <- ifelse(datra$confident_level_r == 0, NA, datra$confident_level_r)
table(datra$confident_level_r_nonzero)

-6 -4 -3 -2 -1  1  2  3  4  6 
 4 12  5 11  4  1  6  2  2  2 
# Run model
receiver_racialized_model_nonzero <- 
  lmer(confident_level_r_nonzero ~ emoji_color + emoji_hand_type + texting_usage_s + (1|id), 
       data = datra)

# Check effects
Anova(receiver_racialized_model_nonzero, type ="2") # emoji_color is significant
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: confident_level_r_nonzero
                 Chisq Df Pr(>Chisq)  
emoji_color     5.9508  2    0.05103 .
emoji_hand_type 0.5351  2    0.76526  
texting_usage_s 0.0889  1    0.76561  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Check summary
report_table(receiver_racialized_model_nonzero)
Parameter                | Coefficient |        95% CI | t(41) |     p | Effects |    Group | Std. Coef. | Std. Coef. 95% CI |    Fit
-------------------------------------------------------------------------------------------------------------------------------------
(Intercept)              |       -1.40 | [-3.64, 0.85] | -1.26 | 0.215 |   fixed |          |       0.04 |     [-0.68, 0.77] |       
emoji color [dark]       |        1.83 | [-0.53, 4.18] |  1.57 | 0.125 |   fixed |          |       0.59 |     [-0.17, 1.34] |       
emoji color [light]      |       -1.67 | [-4.07, 0.73] | -1.40 | 0.168 |   fixed |          |      -0.54 |     [-1.31, 0.24] |       
emoji hand type [peace]  |       -0.14 | [-2.54, 2.26] | -0.12 | 0.907 |   fixed |          |      -0.05 |     [-0.82, 0.73] |       
emoji hand type [thumbs] |       -0.93 | [-3.86, 2.00] | -0.64 | 0.525 |   fixed |          |      -0.30 |     [-1.24, 0.64] |       
texting usage s          |        0.16 | [-0.95, 1.28] |  0.30 | 0.767 |   fixed |          |       0.04 |     [-0.25, 0.34] |       
                         |        0.62 |               |       |       |  random |       id |            |                   |       
                         |        2.96 |               |       |       |  random | Residual |            |                   |       
                         |             |               |       |       |         |          |            |                   |       
AIC                      |             |               |       |       |         |          |            |                   | 248.61
AICc                     |             |               |       |       |         |          |            |                   | 252.21
BIC                      |             |               |       |       |         |          |            |                   | 263.74
R2 (conditional)         |             |               |       |       |         |          |            |                   |   0.18
R2 (marginal)            |             |               |       |       |         |          |            |                   |   0.15
Sigma                    |             |               |       |       |         |          |            |                   |   2.96
# Check quality of the model
check_predictions(receiver_racialized_model_nonzero)

rr_check_nonzero <- simulateResiduals(receiver_racialized_model_nonzero, plot = T)
plot(rr_check_nonzero)

# Calculate the predicted values
rr_emm_nonzero <- emmeans(receiver_racialized_model_nonzero, ~ emoji_color, adjust = "sidak")

# Calculate the comparisons
model_parameters(
  emmeans::contrast(rr_emm_nonzero),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high t df_error p
yellow effect -0.0523177 0.6393779 0.95 -1.351689 1.2470538 -0.081826 34.00051 0.9352649
dark effect 1.7733948 0.7978232 0.95 0.157916 3.3888736 2.222792 37.73673 0.0617537
light effect -1.7210771 0.8126339 0.95 -3.369280 -0.0728746 -2.117900 35.93443 0.0617537
model_parameters(
  emmeans::contrast(rr_emm_nonzero, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high t df_error p
yellow - dark -1.825713 1.195942 0.95 -4.2500402 0.5986152 -1.526589 36.50118 0.1822285
yellow - light 1.668759 1.225493 0.95 -0.8215549 4.1590736 1.361704 34.06981 0.1822285
dark - light 3.494472 1.478170 0.95 0.5003444 6.4885993 2.364052 37.34367 0.0701566
# Check if all levels of emoji colors are different from 0
# Subset the data for each level of emoji_color
data_dark <- datra$confident_level_r_nonzero[datra$emoji_color == "dark"]
data_light <- datra$confident_level_r_nonzero[datra$emoji_color == "light"]
data_yellow <- datra$confident_level_r_nonzero[datra$emoji_color == "yellow"]

# Run the Anderson-Darling test for normality
ad.test(data_dark)

    Anderson-Darling normality test

data:  data_dark
A = 0.90082, p-value = 0.01734
ad.test(data_light)

    Anderson-Darling normality test

data:  data_light
A = 0.72381, p-value = 0.04522
ad.test(data_yellow)

    Anderson-Darling normality test

data:  data_yellow
A = 0.61496, p-value = 0.08893
# Perform Wilcoxon signed-rank test for each subset against 0
# Note: Using paired = FALSE for one-sample scenario
test_dark <- wilcox.test(data_dark, mu = 0, paired = FALSE, exact = FALSE)
test_light <- wilcox.test(data_light, mu = 0, paired = FALSE, exact = FALSE)
test_yellow <- wilcox.test(data_yellow, mu = 0, paired = FALSE, exact = FALSE)

de <- c(test_dark$p.value,
        test_light$p.value,
        test_yellow$p.value)

fdrs <- p.adjust(de, method = "BH")
fdrs
[1] 0.720949904 0.002922841 0.096255466
group_by(datra, emoji_color) %>%
  summarise(
    count = n(),
    median = median(confident_level_r_nonzero, na.rm = TRUE),
    sd = sd(confident_level_r_nonzero, na.rm = TRUE))
# A tibble: 3 × 4
  emoji_color count median    sd
  <fct>       <int>  <dbl> <dbl>
1 yellow         76     -2  3.13
2 dark           76     -1  3.54
3 light          76     -3  1.33
# Estimated means plot
# Generate interaction-style plot for estimated marginal means
rr_plot <- emmip(receiver_racialized_model_nonzero, ~ emoji_color, CIs = TRUE, type = "response")
rr_df_p <- rr_plot$data

rr_df_p <- rr_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color))

rr_plota <-
  ggplot(rr_df_p, aes(
    x = emoji_color,
    y = yvar,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = 0,
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Emojis\n", y = "Confidence Levels about Receivers'\nRacialized Profile on Neutral Condition\n") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'none',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
    scale_y_continuous(
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip()  +
  annotate("text", x = Inf, y = Inf, label = "Black", hjust = 1.5, vjust = 1.9, color = "gray40") +
  annotate("text", x = Inf, y = -Inf, label = "White", hjust = -0.4, vjust = 1.9, color = "gray40")
rr_plota

rm(list = ls(pattern = "^rr_"))

Reading Times

# General distribution
hist_boxplot(dfp$rt_key_conversation, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(dfp, aes(x = rt_key_conversation)) +
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") +
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

## Base model without interaction
reading_base <- glmmTMB(rt_key_conversation ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)

## Check effects
Anova(reading_base, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: rt_key_conversation
                  Chisq Df Pr(>Chisq)    
emoji_color      5.6021  2   0.060747 .  
profile_pic      2.9137  2   0.232967    
emoji_hand_type 26.1373  2 0.00000211 ***
texting_usage_s 10.0039  1   0.001562 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Model with interaction
reading_base_int <- glmmTMB(rt_key_conversation ~ 1 + emoji_color * profile_pic + 
                              emoji_hand_type + texting_usage_s + (1|id),
                            family = Gamma(link = "log"),
                            data = dfp)
## Check effects
Anova(reading_base_int, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: rt_key_conversation
                             Chisq Df            Pr(>Chisq)    
(Intercept)             27492.8906  1 < 0.00000000000000022 ***
emoji_color                 2.8989  2              0.234697    
profile_pic                 3.5536  2              0.169182    
emoji_hand_type            26.0180  2            0.00000224 ***
texting_usage_s             9.9869  1              0.001577 ** 
emoji_color:profile_pic     1.6786  4              0.794594    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Estimated means plot

# Generate interaction-style plot for estimated marginal means
re_plot <- emmip(reading_base, ~ emoji_color * profile_pic, CIs = TRUE, type = "response")
re_df_p <- re_plot$data

re_df_p <- re_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color),
         profile_pic = str_to_title(profile_pic))

re_df_p$profile_pic <- factor(re_df_p$profile_pic, levels = c("Neutral",
                                                              "Black",
                                                              "White"))
re_plotc <-
  ggplot(re_df_p, aes(
    x = profile_pic,
    y = yvar,
    group = emoji_color,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(re_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Profile Picture\n", y = "Estimated Reading Times\n", color = "Skin Tone Emojis") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'bottom',
    legend.justification = 'center',
    legend.direction = 'horizontal',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
    scale_y_continuous(
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

re_plotc

rm(list = ls(pattern = "^re_"))

Response Time

m0 <- glmmTMB(rt_sender_competence ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)
Anova(m0, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: rt_sender_competence
                 Chisq Df Pr(>Chisq)   
emoji_color     1.6280  2   0.443088   
profile_pic     0.3627  2   0.834142   
emoji_hand_type 3.5178  2   0.172234   
texting_usage_s 8.9324  1   0.002801 **
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
m1 <- glmmTMB(rt_sender_competence ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)
Anova(m1, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: rt_sender_competence
                             Chisq Df           Pr(>Chisq)    
(Intercept)             12102.0300  1 < 0.0000000000000002 ***
emoji_color                 1.0758  2              0.58396    
profile_pic                 0.1987  2              0.90544    
emoji_hand_type             2.6219  2              0.26956    
texting_usage_s             8.9272  1              0.00281 ** 
emoji_color:profile_pic     1.5683  4              0.81447    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
m2 <- glmmTMB(rt_sender_warmth ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)
Anova(m2, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: rt_sender_warmth
                 Chisq Df Pr(>Chisq)   
emoji_color     0.8037  2   0.669080   
profile_pic     1.5090  2   0.470256   
emoji_hand_type 0.3705  2   0.830896   
texting_usage_s 6.7378  1   0.009439 **
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
m3 <- glmmTMB(rt_sender_warmth ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)
Anova(m3, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: rt_sender_warmth
                             Chisq Df            Pr(>Chisq)    
(Intercept)             10564.0896  1 < 0.00000000000000022 ***
emoji_color                 0.6880  2              0.708927    
profile_pic                 0.6594  2              0.719144    
emoji_hand_type             0.3200  2              0.852137    
texting_usage_s             6.7770  1              0.009234 ** 
emoji_color:profile_pic     2.1169  4              0.714266    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
m4 <- glmmTMB(rt_quality_relationship ~ 1 + emoji_color + profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)
Anova(m4, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: rt_quality_relationship
                  Chisq Df Pr(>Chisq)   
emoji_color      3.1473  2   0.207292   
profile_pic      1.9643  2   0.374497   
emoji_hand_type  8.6654  2   0.013132 * 
texting_usage_s 10.1584  1   0.001436 **
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
m5 <- glmmTMB(rt_quality_relationship ~ 1 + emoji_color * profile_pic + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)
Anova(m5, type = "3")
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: rt_quality_relationship
                             Chisq Df            Pr(>Chisq)    
(Intercept)             12678.5272  1 < 0.00000000000000022 ***
emoji_color                 3.3619  2              0.186193    
profile_pic                 0.9990  2              0.606837    
emoji_hand_type             6.1896  2              0.045284 *  
texting_usage_s            10.4268  1              0.001242 ** 
emoji_color:profile_pic     2.8177  4              0.588774    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

rt_sender_black

# General distribution
hist_boxplot(dfp$rt_sender_black, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(dfp, aes(x = rt_sender_black)) +
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") +
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

## Base model
react_b_base <- glmmTMB(rt_sender_black ~ 1 + emoji_color + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)

## Check effects
Anova(react_b_base, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: rt_sender_black
                 Chisq Df Pr(>Chisq)  
emoji_color     7.7245  2    0.02102 *
emoji_hand_type 6.1385  2    0.04646 *
texting_usage_s 2.1878  1    0.13911  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
report_table(react_b_base)
Parameter                | Coefficient |         95% CI |      z |  df |      p | Effects | Group |   Component | Std. Coef. | Std. Coef. 95% CI |      Fit
-----------------------------------------------------------------------------------------------------------------------------------------------------------
(Intercept)              |        7.92 | [ 7.78,  8.07] | 108.15 | Inf | < .001 |   fixed |       | conditional |       7.92 |    [ 7.78,  8.07] |         
(Intercept)              |        0.77 | [ 0.73,  0.81] |        |     |        |   fixed |       |  dispersion |       7.92 |    [ 7.78,  8.07] |         
emoji color [dark]       |        0.11 | [-0.03,  0.26] |   1.52 | Inf | 0.128  |   fixed |       | conditional |       0.11 |    [-0.03,  0.26] |         
emoji color [light]      |       -0.10 | [-0.25,  0.05] |  -1.30 | Inf | 0.194  |   fixed |       | conditional |      -0.10 |    [-0.25,  0.05] |         
emoji hand type [peace]  |        0.03 | [-0.12,  0.18] |   0.41 | Inf | 0.682  |   fixed |       | conditional |       0.03 |    [-0.12,  0.18] |         
emoji hand type [thumbs] |       -0.15 | [-0.30,  0.00] |  -1.97 | Inf | 0.049  |   fixed |       | conditional |      -0.15 |    [-0.30,  0.00] |         
texting usage s          |       -0.06 | [-0.14,  0.02] |  -1.48 | Inf | 0.139  |   fixed |       | conditional |      -0.06 |    [-0.14,  0.02] |         
                         |        0.26 |                |        |     |        |  random |    id | conditional |            |                   |         
                         |             |                |        |     |        |         |       |             |            |                   |         
AIC                      |             |                |        |     |        |         |       |             |            |                   | 12128.82
AICc                     |             |                |        |     |        |         |       |             |            |                   | 12129.04
BIC                      |             |                |        |     |        |         |       |             |            |                   | 12165.05
R2 (conditional)         |             |                |        |     |        |         |       |             |            |                   |     0.12
R2 (marginal)            |             |                |        |     |        |         |       |             |            |                   |     0.02
Sigma                    |             |                |        |     |        |         |       |             |            |                   |     0.77
# Calculate the predicted values
re_emm <- emmeans(react_b_base, ~ emoji_color)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(re_emm, interaction = FALSE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow effect -0.0043136 0.0433841 0.95 -0.0893448 0.0807176 -0.0994287 Inf 0.9207979
dark effect 0.1085393 0.0432794 0.95 0.0237132 0.1933654 2.5078731 Inf 0.0304300
light effect -0.1042257 0.0449054 0.95 -0.1922387 -0.0162126 -2.3210035 Inf 0.0304300
model_parameters(
  emmeans::contrast(re_emm, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow - dark -0.1128529 0.0741220 0.95 -0.2581294 0.0324235 -1.522529 Inf 0.1918147
yellow - light 0.0999121 0.0769691 0.95 -0.0509446 0.2507687 1.298080 Inf 0.1942597
dark - light 0.2127650 0.0767922 0.95 0.0622551 0.3632749 2.770660 Inf 0.0167829
# Estimated means plot
# Generate interaction-style plot for estimated marginal means
re_plot <- emmip(react_b_base, ~ emoji_color, CIs = TRUE, type = "response")
re_df_p <- re_plot$data

re_df_p <- re_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color))

re_plota <-
  ggplot(re_df_p, aes(
    x = emoji_color,
    y = yvar,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(re_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Emojis\n", y = "Reaction time Estimated Receiver's Racialized Identity being Black\n") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'none',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
  scale_y_continuous(
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

re_plota

rt_sender_white

# General distribution
hist_boxplot(dfp$rt_sender_white, col = "lightblue", freq = T, density = F)

# Distribution by condition
ggplot(dfp, aes(x = rt_sender_white)) +
  geom_histogram(aes(y = after_stat(density)), position = "identity", bins = 20, fill = "lightblue") +
  geom_boxplot(aes(y = 0), width = 0.1) +
  facet_wrap(~ emoji_color + profile_pic, scales = "free_y") +
  theme_minimal()

## Base model without interaction
react_w_base <- glmmTMB(rt_sender_white ~ 1 + emoji_color + emoji_hand_type + texting_usage_s + (1|id),
                   family = Gamma(link = "log"), 
                   data = dfp)

## Check effects
Anova(react_w_base, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: rt_sender_white
                 Chisq Df Pr(>Chisq)  
emoji_color     5.7190  2    0.05730 .
emoji_hand_type 0.1183  2    0.94255  
texting_usage_s 6.2776  1    0.01223 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Check summary
report_table(react_w_base)
Parameter                | Coefficient |         95% CI |      z |  df |      p | Effects | Group |   Component | Std. Coef. | Std. Coef. 95% CI |      Fit
-----------------------------------------------------------------------------------------------------------------------------------------------------------
(Intercept)              |        8.52 | [ 8.40,  8.63] | 143.71 | Inf | < .001 |   fixed |       | conditional |       8.52 |    [ 8.40,  8.63] |         
(Intercept)              |        0.60 | [ 0.57,  0.63] |        |     |        |   fixed |       |  dispersion |       8.52 |    [ 8.40,  8.63] |         
emoji color [dark]       |        0.12 | [ 0.00,  0.23] |   2.03 | Inf | 0.042  |   fixed |       | conditional |       0.12 |    [ 0.00,  0.23] |         
emoji color [light]      |   -8.06e-03 | [-0.12,  0.11] |  -0.14 | Inf | 0.892  |   fixed |       | conditional |  -8.05e-03 |    [-0.12,  0.11] |         
emoji hand type [peace]  |        0.02 | [-0.09,  0.13] |   0.34 | Inf | 0.731  |   fixed |       | conditional |       0.02 |    [-0.09,  0.13] |         
emoji hand type [thumbs] |    9.22e-03 | [-0.11,  0.13] |   0.16 | Inf | 0.877  |   fixed |       | conditional |   9.24e-03 |    [-0.11,  0.13] |         
texting usage s          |       -0.09 | [-0.16, -0.02] |  -2.51 | Inf | 0.012  |   fixed |       | conditional |      -0.09 |    [-0.16, -0.02] |         
                         |        0.25 |                |        |     |        |  random |    id | conditional |            |                   |         
                         |             |                |        |     |        |         |       |             |            |                   |         
AIC                      |             |                |        |     |        |         |       |             |            |                   | 12867.80
AICc                     |             |                |        |     |        |         |       |             |            |                   | 12868.01
BIC                      |             |                |        |     |        |         |       |             |            |                   | 12904.02
R2 (conditional)         |             |                |        |     |        |         |       |             |            |                   |     0.17
R2 (marginal)            |             |                |        |     |        |         |       |             |            |                   |     0.03
Sigma                    |             |                |        |     |        |         |       |             |            |                   |     0.60
# Calculate the predicted values
re_emm <- emmeans(react_w_base, ~ emoji_color)

# Calculate the comparisons
model_parameters(
  emmeans::contrast(re_emm, interaction = FALSE),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow effect -0.0363605 0.0336008 0.95 -0.1022168 0.0294957 -1.082134 Inf 0.2791928
dark effect 0.0807846 0.0337854 0.95 0.0145664 0.1470028 2.391108 Inf 0.0503928
light effect -0.0444241 0.0347817 0.95 -0.1125949 0.0237468 -1.277227 Inf 0.2791928
model_parameters(
  emmeans::contrast(re_emm, interaction = FALSE, method = "pairwise"),
  ci = 0.95,
  bootstrap = TRUE,
  iterations = 10000,
  p_adjust = "fdr"
) %>%
  kbl(table.attr = 'data-quarto-disable-processing="true"') %>%
  kable_styling(full_width = T, c("striped", "hover"))
contrast Coefficient SE CI CI_low CI_high z df_error p
yellow - dark -0.1171451 0.0577163 0.95 -0.2302669 -0.0040234 -2.0296732 Inf 0.0635847
yellow - light 0.0080635 0.0594651 0.95 -0.1084859 0.1246130 0.1356013 Inf 0.8921365
dark - light 0.1252087 0.0597782 0.95 0.0080456 0.2423717 2.0945557 Inf 0.0635847
# Estimated means plot
# Generate interaction-style plot for estimated marginal means
re_plot <- emmip(react_w_base, ~ emoji_color, CIs = TRUE, type = "response")
re_df_p <- re_plot$data

re_df_p <- re_df_p %>%
  mutate(emoji_color = str_to_title(emoji_color))

re_plotd <-
  ggplot(re_df_p, aes(
    x = emoji_color,
    y = yvar,
    color = emoji_color, shape = emoji_color
  )) +
  geom_hline(
    yintercept = mean(re_df_p$yvar),
    linetype = "dashed",
    color = "gray80",
    linewidth = 0.5
  ) +
  with_shadow(
    geom_point(position = position_dodge(width = 0.5), size = 5.4, alpha = 1, stroke = 0), 
    sigma = 4, colour = "gray80", x_offset = 2, y_offset = 2) +  
  geom_errorbar(
    aes(ymin = LCL, ymax = UCL),
    width = 0,
    linewidth = 1.8,
    alpha = 0.7,
    position = position_dodge(width = 0.5)
  ) +
  labs(x = "Emojis\n", y = "Reaction time Estimated Receiver's Racialized Identity being White\n") +
  theme_minimal() +
  theme(aspect.ratio = 1/1,
    plot.title = element_text(hjust = 1, size = 10),
    legend.position = 'none',
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.border = element_rect(
      color = "black",
      fill = NA,
      linewidth = 0.5
    ),
    axis.text.x = element_text(size = rel(1.2)),
    axis.text.y = element_text(size = rel(1.2))
  ) +
    scale_y_continuous(
    position = "right"
  ) +
  scale_color_manual(values = colors,     guide = guide_legend(override.aes = list(shape = c(15, 17, 16)))) + scale_shape_manual(values = c("Yellow" = 15, "Light" = 17, "Dark" = 16)) + guides(shape = "none") + coord_flip() 

re_plotd

rm(list = ls(pattern = "^re_"))

Volunteers versus Credit

m1 <-
  clmm(
    sender_competence_f ~ 1 + volunteer + (1 | id),
    data = dfp, link = "logit", threshold = "flexible")
RVAideMemoire::Anova.clmm(m1, type = "2")
Analysis of Deviance Table (Type II tests)

Response: sender_competence_f
          LR Chisq Df Pr(>Chisq)
volunteer   1.0245  1     0.3115
m2 <-
  clmm(
    sender_warmth_f ~ 1 + volunteer + (1 | id),
    data = dfp, link = "logit", threshold = "flexible")
RVAideMemoire::Anova.clmm(m2, type = "2")
Analysis of Deviance Table (Type II tests)

Response: sender_warmth_f
          LR Chisq Df Pr(>Chisq)
volunteer  0.74805  1     0.3871
m3 <-
  clmm(
    quality_relationship_f ~ 1 + volunteer + (1 | id),
    data = dfp, link = "logit", threshold = "flexible")
RVAideMemoire::Anova.clmm(m3, type = "2")
Analysis of Deviance Table (Type II tests)

Response: quality_relationship_f
          LR Chisq Df Pr(>Chisq)
volunteer  0.11858  1     0.7306
m4 <- lmer(confident_level_nonzero ~ 1 + volunteer + (1|id), data = datra)
Anova(m4, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: confident_level_nonzero
           Chisq Df Pr(>Chisq)
volunteer 0.2054  1     0.6504
m5 <- glmmTMB(ia_dwell_time ~ 1 + volunteer + (1|id), family = Gamma(link = "log"), data = dfe)
Anova(m5, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_dwell_time
           Chisq Df Pr(>Chisq)
volunteer 0.0184  1     0.8921
m6 <- glmmTMB(ia_dwell_time ~ 1 + volunteer + (1|id), family = Gamma(link = "log"), data = dfp)
Anova(m6, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_dwell_time
           Chisq Df Pr(>Chisq)
volunteer 0.6959  1     0.4042
m7 <- glmmTMB(ia_run_count ~ 1 + volunteer + (1|id), family = genpois(link = "log"), data = dfe)
Anova(m7, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_run_count
           Chisq Df Pr(>Chisq)
volunteer 1.9785  1     0.1596
m8 <- glmmTMB(ia_run_count ~ 1 + volunteer + (1|id), family = genpois(link = "log"), data = dfp)
Anova(m8, type = "2")
Analysis of Deviance Table (Type II Wald chisquare tests)

Response: ia_run_count
           Chisq Df Pr(>Chisq)
volunteer 0.9162  1     0.3385
rm(m1, m2, m3, m4, m5, m6, m7, m8)

Information About the Packages

sessionInfo()
R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS 15.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Amsterdam
tzcode source: internal

attached base packages:
[1] parallel  splines   stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] parameters_0.21.6      nortest_1.0-4          effectsize_0.8.6       gamlss_5.4-20          nlme_3.1-163           gamlss.dist_6.1-1      gamlss.data_6.0-2      glmmTMB_1.1.9          DHARMa_0.4.6           Hmisc_5.1-1            report_0.5.8           sjPlot_2.8.15          lme4_1.1-35.1          Matrix_1.6-5           emmeans_1.10.0         RVAideMemoire_0.9-83-7 ordinal_2023.12-4      car_3.1-2              carData_3.0-5          performance_0.11.0     rstatix_0.7.2          psych_2.3.12           packHV_2.2             survival_3.5-7         vtable_1.4.6           kableExtra_1.3.4       sur_1.0.4              ggfx_1.0.1             ggplot2_3.5.1          janitor_2.2.0          stringr_1.5.1          tidyr_1.3.1            dplyr_1.1.4            readr_2.1.5            qualtRics_3.2.0       

loaded via a namespace (and not attached):
  [1] later_1.3.2           tibble_3.2.1          datawizard_0.9.1      rpart_4.1.21          lifecycle_1.0.4       Rdpack_2.6            doParallel_1.0.17     lattice_0.21-9        vroom_1.6.5           MASS_7.3-60           insight_0.19.10       backports_1.4.1       magrittr_2.0.3        rmarkdown_2.25        yaml_2.3.8            httpuv_1.6.13         gap_1.5-3             RColorBrewer_1.1-3    minqa_1.2.6           lubridate_1.9.3       multcomp_1.4-25       abind_1.4-5           rvest_1.0.3           purrr_1.0.2           nnet_7.3-19           WriteXLS_6.5.0        TH.data_1.1-2         sandwich_3.1-0        pbkrtest_0.5.2        svglite_2.1.3         codetools_0.2-19      xml2_1.3.6            tidyselect_1.2.0      ggeffects_1.5.1       farver_2.1.1          base64enc_0.1-3       webshot_0.5.5         jsonlite_1.8.8        Formula_1.2-5         iterators_1.0.14     
 [41] systemfonts_1.0.5     foreach_1.5.2         tools_4.3.2           ragg_1.2.7            Rcpp_1.0.12           glue_1.7.0            mnormt_2.1.1          gridExtra_2.3         xfun_0.41             mgcv_1.9-0            withr_2.5.2           numDeriv_2016.8-1.1   fastmap_1.2.0         boot_1.3-28.1         fansi_1.0.6           digest_0.6.34         timechange_0.2.0      R6_2.5.1              mime_0.12             estimability_1.4.1    textshaping_0.3.7     colorspace_2.1-0      see_0.8.1             utf8_1.2.4            generics_0.1.3        data.table_1.15.4     httr_1.4.7            htmlwidgets_1.6.4     pkgconfig_2.0.3       gtable_0.3.4          htmltools_0.5.7       TMB_1.9.10            scales_1.3.0          snakecase_0.11.1      knitr_1.45            rstudioapi_0.16.0     tzdb_0.4.0            coda_0.19-4           checkmate_2.3.1       nloptr_2.0.3         
 [81] zoo_1.8-12            sjlabelled_1.2.0      foreign_0.8-85        pillar_1.9.0          grid_4.3.2            vctrs_0.6.5           promises_1.2.1        ucminf_1.2.1          xtable_1.8-4          cluster_2.1.4         GPArotation_2023.11-1 htmlTable_2.4.2       evaluate_0.23         magick_2.8.2          mvtnorm_1.2-4         cli_3.6.2             compiler_4.3.2        rlang_1.1.3           crayon_1.5.2          modelr_0.1.11         labeling_0.4.3        plyr_1.8.9            sjmisc_2.8.9          forcats_1.0.0         gap.datasets_0.0.6    stringi_1.8.3         viridisLite_0.4.2     munsell_0.5.0         bayestestR_0.13.2     sjstats_0.18.2        hms_1.1.3             bit64_4.0.5           qgam_1.3.4            shiny_1.9.1           highr_0.10            haven_2.5.4           rbibutils_2.2.16      broom_1.0.5           bit_4.0.5